java7中,新增了Files这个强大的工具类,我们就围绕着这个Files类,来看看它的读取和写入吧
在resources中,有一个a.json
的文件, 模拟读取这个json文件.
废话不多说,上代码:
package com.zgd.demo.file.rw;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: zgd
* @Date: 2019/3/1 15:01
* @Description:
*/
public class ReadFiles {
public static void main(String[] args) {
String s = "a.json";
readFile(s);
System.out.println("------------");
System.out.println("getFileToString(s).size() = " + getFileToString(s).size());
System.out.println("------------");
System.out.println("getFileBufferToString(s).size() = " + getFileBufferToString(s).size());
}
/**
* 读取文件
* @param fileName
*/
public static void readFile(String fileName){
try {
//相对路径的写法
//
Files.lines(Paths.get(ReadFiles.class.getResource("/"+fileName).getPath().substring(1))).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取文件为字符串
* @param fileName
*/
public static List<String> getFileToString(String fileName){
try {
return Files.readAllLines(Paths.get(ReadFiles.class.getResource("/"+fileName).getPath().substring(1)));
} catch (IOException e) {
e.printStackTrace();
}
return Collections.emptyList();
}
/**
* 使用字符缓冲流 获取文件为字符串
* @param fileName
*/
public static List<String> getFileBufferToString(String fileName){
try {
BufferedReader bufferedReader = Files.newBufferedReader(Paths.get(ReadFiles.class.getResource("/" + fileName).getPath().substring(1)));
//方式一,直接使用java8的lambda,一条语句
return bufferedReader.lines().collect(Collectors.toList());
/*
//第二种方式
List s = Collections.emptyList();
String line ;
while ((line = bufferedReader.readLine()) != null){
s.add(line);
}
if (bufferedReader != null){
bufferedReader.close();
}
return s;
*/
} catch (IOException e) {
e.printStackTrace();
}
return Collections.emptyList();
}
}
控制台输出:
{
"RECORDS":[
{
"user_id":1045557565091545088,
"biz_code":12154510359328150,
"biz_type":3,
"cert_info_id":1057169878429007872
},
{
"user_id":1048592603915812864,
"biz_code":1538838933356864,
"biz_type":3,
"cert_info_id":1055676750073233408
}
]
}
------------
getFileToString(s).size() = 16
------------
getFileBufferToString(s).size() = 16
Process finished with exit code 0
package com.zgd.demo.file.rw;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
/**
* @Author: zgd
* @Date: 2019/3/1 15:01
* @Description:
*/
public class WriteFiles {
public static void main(String[] args) {
List<String> lines = Arrays.asList("这是第一行", "这是第二行");
writeFileToTarget("b.txt",lines);
writeFileToDest("E:/bb.txt",lines);
writeBufferFileToDest("E:/aa.txt",lines);
}
/**
* 写入文件到/target/classes
*
* @param destFile
*/
public static void writeFileToTarget(String destFile, List<String> lines) {
try {
Path path = Paths.get(WriteFiles.class.getResource("/").getPath().substring(1) + destFile);
// if (!Files.exists(path)){
// Files.createFile(path);
// }
//可以选择传入第三个OpenOptions参数,不传入默认CREATE和TRUNCATE_NEW,即如果文件不存在,创建该文件,如果存在,覆盖
// Files.write(path, lines);
// 如果不传第三个参数,则文件不存在的话默认会选择创建
Files.write(path, lines);
//还可以传入第三个参数,选择是否创建文件,是否在同名文件后拼接等
// Files.write(path,lines, StandardOpenOption.CREATE,StandardOpenOption.APPEND );
System.out.println("已写入完成.path = " + path);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写入文件到指定绝对路径
*
* @param destPath
*/
public static void writeFileToDest(String destPath, List<String> lines) {
try {
Path path = Paths.get(destPath);
// if (!Files.exists(path)){
// Files.createFile(path);
// }
//可以选择传入第三个OpenOptions参数,不传入默认CREATE和TRUNCATE_NEW,即如果文件不存在,创建该文件,如果存在,覆盖
// Files.write(path, lines,StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING);
Files.write(path, lines);
System.out.println("已写入完成.path = " + path);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 字符缓冲流写入文件到指定绝对路径
*
* @param destPath
*/
public static void writeBufferFileToDest(String destPath, List<String> lines) {
try {
Path path = Paths.get(destPath);
if (!Files.exists(path)){
Files.createFile(path);
}
BufferedWriter bufferedWriter = Files.newBufferedWriter(path);
lines.stream().forEach(s -> {
try {
bufferedWriter.write(s);
bufferedWriter.newLine();
} catch (IOException e) {
e.printStackTrace();
}
});
bufferedWriter.close();
System.out.println("已写入完成.path = " + path);
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里使用三种方式来拷贝. java7的Files工具类,NIO的通道,原始的输入输出流,拷贝tomcat压缩包,大小10M左右.
package com.zgd.demo.file.rw;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
/**
* @Author: zgd
* @Date: 2019/3/1 15:01
* @Description:
*/
public class CopyFiles {
public static void main(String[] args) {
String ref = "E:/apache-tomcat-8.5.31.zip";
String dest = "E:/pache-tomcat-8.5.31-copy.zip";
Instant s = Instant.now();
copyFileByFiles(ref, dest);
System.out.println("copyFileByFiles = " + ChronoUnit.MILLIS.between(s, Instant.now()));
s = Instant.now();
copyFileChannel(ref, dest);
System.out.println("copyFileChannel = " + ChronoUnit.MILLIS.between(s, Instant.now()));
s = Instant.now();
copyFileUsingFileStreams(ref, dest);
System.out.println("copyFileUsingFileStreams = " + ChronoUnit.MILLIS.between(s, Instant.now()));
}
/**
* 使用java7的Files
*
* @param refPath
* @param destPath
*/
public static void copyFileByFiles(String refPath, String destPath) {
Path old = Paths.get(refPath);
Path copy = Paths.get(destPath);
try {
//默认不会覆盖同名文件
// Files.copy(old,copy);
//传入第三个参数,使其可以覆盖同名文件
Files.copy(old, copy, StandardCopyOption.REPLACE_EXISTING);
System.out.println("拷贝完成");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Java NIO包括transferFrom方法,根据文档应该比文件流复制的速度更快
*
* @param refPath
* @param destPath
*/
public static void copyFileChannel(String refPath, String destPath) {
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
inputChannel = new FileInputStream(refPath).getChannel();
outputChannel = new FileOutputStream(destPath).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
System.out.println("拷贝完成");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputChannel != null) {
inputChannel.close();
}
if (inputChannel != null) {
outputChannel.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 原始的输入输出流复制法
*
* @param source
* @param dest
* @throws IOException
*/
public static void copyFileUsingFileStreams(String source, String dest) {
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(source);
output = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
System.out.println("拷贝完成");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
根据控制台:
拷贝完成
copyFileByFiles = 16
拷贝完成
copyFileChannel = 11
拷贝完成
copyFileUsingFileStreams = 84
可以看出最快的还是NIO通道,但是Files工具类也不慢
综合起来,Files工具类是最简洁的,只要一行代码搞定,NIO和流都很繁杂. 所以个人还是喜欢Files