1. 使用流读取文件
public static void stream() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), CHARSET_NAME))) {
String line;
while ((line = br.readLine()) != null) {
content.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
2. 使用JDK1.7提供的NIO读取文件(适用于小文件)
public static void nioOfJDK7() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = new ArrayList<>(0);
try {
content = Files.readAllLines(Paths.get(fileName), Charset.forName(CHARSET_NAME));
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
3. 使用JDK1.7提供的NIO读取文件(适用于大文件)
public static void streamOfJDK7() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = new ArrayList<>();
try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName), Charset.forName(CHARSET_NAME))) {
String line;
while ((line = br.readLine()) != null) {
content.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
4. 使用JDK1.4提供的NIO读取文件(适用于超大文件)
public static void nioOfJDK4() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
final int ASCII_LF = 10; // 换行符
final int ASCII_CR = 13; // 回车符
List<String> content = new ArrayList<>();
try (FileChannel fileChannel = new RandomAccessFile(fileName, "r").getChannel()) {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 100);
byte[] lineByte;
byte[] temp = new byte[0];
while (fileChannel.read(byteBuffer) != -1) {
// 获取缓冲区位置,即读取长度
int readSize = byteBuffer.position();
// 将读取位置置0,并将读取位置标为废弃
byteBuffer.rewind();
// 读取内容
byte[] readByte = new byte[readSize];
byteBuffer.get(readByte);
// 清除缓存区
byteBuffer.clear();
// 读取内容是否包含一整行
boolean hasLF = false;
int startNum = 0;
for (int i = 0; i < readSize; i++) {
if (readByte[i] == ASCII_LF) {
hasLF = true;
int tempNum = temp.length;
int lineNum = i - startNum;
// 数组大小已经去掉换行符
lineByte = new byte[tempNum + lineNum];
System.arraycopy(temp, 0, lineByte, 0, tempNum);
temp = new byte[0];
System.arraycopy(readByte, startNum, lineByte, tempNum, lineNum);
String line = new String(lineByte, 0, lineByte.length, CHARSET_NAME);
content.add(line);
// 过滤回车符和换行符
if (i + 1 < readSize && readByte[i + 1] == ASCII_CR) {
startNum = i + 2;
} else {
startNum = i + 1;
}
}
}
if (hasLF) {
temp = new byte[readByte.length - startNum];
System.arraycopy(readByte, startNum, temp, 0, temp.length);
} else {
// 单次读取的内容不足一行的情况
byte[] toTemp = new byte[temp.length + readByte.length];
System.arraycopy(temp, 0, toTemp, 0, temp.length);
System.arraycopy(readByte, 0, toTemp, temp.length, readByte.length);
temp = toTemp;
}
}
// 最后一行
if (temp.length > 0) {
String lastLine = new String(temp, 0, temp.length, CHARSET_NAME);
content.add(lastLine);
}
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
5. 使用cmmons-io依赖提供的FileUtils工具类读取文件
添加依赖:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
public static void fileOfCommonsIO() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = new ArrayList<>(0);
try {
content = FileUtils.readLines(new File(fileName), CHARSET_NAME);
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
6. 使用cmmons-io依赖提供的IOtils工具类读取文件
添加依赖:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
public static void ioOfCommonsIO() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = new ArrayList<>(0);
try {
content = IOUtils.readLines(new FileInputStream(fileName), CHARSET_NAME);
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
7. 使用hutool依赖提供的FileUtil工具类读取文件
添加依赖:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.10</version>
</dependency>
或者:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.10</version>
</dependency>
public static void fileOfHutool() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = FileUtil.readLines(fileName, CHARSET_NAME);
// content.forEach(System.out::println);
System.out.println(content.size());
}
8. 使用hutool依赖提供的IoUtil工具类读取文件
添加依赖:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.10</version>
</dependency>
或者:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.10</version>
</dependency>
public static void ioOfHutool() {
String fileName = "D:\\test.txt";
final String CHARSET_NAME = "UTF-8";
List<String> content = new ArrayList<>();
try {
IoUtil.readLines(new FileInputStream(fileName), CharsetUtil.charset(CHARSET_NAME), content);
} catch (Exception e) {
e.printStackTrace();
}
// content.forEach(System.out::println);
System.out.println(content.size());
}
9. 测试耗时
测试文件:30000行、21.8 MB
public static void main(String[] args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("stream");
stream();
stopWatch.stop();
stopWatch.start("nioOfJDK7");
nioOfJDK7();
stopWatch.stop();
stopWatch.start("streamOfJDK7");
streamOfJDK7();
stopWatch.stop();
stopWatch.start("nioOfJDK4");
nioOfJDK4();
stopWatch.stop();
stopWatch.start("fileOfCommonsIO");
fileOfCommonsIO();
stopWatch.stop();
stopWatch.start("ioOfCommonsIO");
ioOfCommonsIO();
stopWatch.stop();
stopWatch.start("fileOfHutool");
fileOfHutool();
stopWatch.stop();
stopWatch.start("ioOfHutool");
ioOfHutool();
stopWatch.stop();
for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) {
System.out.println(taskInfo.getTaskName() + " -> " + taskInfo.getTimeMillis() + " ms");
}
// System.out.println(stopWatch.prettyPrint());
}
测试3次耗时统计(单位:ms):
测试序号streamnioOfJDK7streamOfJDK7nioOfJDK4fileOfCommonsIOioOfCommonsIOfileOfHutoolioOfHutool11101138521410964178602981267723613570169593106122902241306816562
从测试结果来看,Hutool提供的IoUtil、commons-io提供的IoUtil以及JDK1.7提供的NIO基于流方式耗时更优,但测试还应参考内存占用情况,具体可自行测试。
版权归原作者 C3Stones 所有, 如有侵权,请联系我们删除。