Java讀取文件的幾種方式詳細(xì)總結(jié)
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) {
// 獲取緩沖區(qū)位置,即讀取長度
int readSize = byteBuffer.position();
// 將讀取位置置0,并將讀取位置標(biāo)為廢棄
byteBuffer.rewind();
// 讀取內(nèi)容
byte[] readByte = new byte[readSize];
byteBuffer.get(readByte);
// 清除緩存區(qū)
byteBuffer.clear();
// 讀取內(nèi)容是否包含一整行
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;
// 數(shù)組大小已經(jīng)去掉換行符
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 {
// 單次讀取的內(nèi)容不足一行的情況
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次耗時統(tǒng)計(單位:ms):
| 測試序號 | stream | nioOfJDK7 | streamOfJDK7 | nioOfJDK4 | fileOfCommonsIO | ioOfCommonsIO | fileOfHutool | ioOfHutool |
|---|---|---|---|---|---|---|---|---|
| 1 | 110 | 113 | 85 | 214 | 109 | 64 | 178 | 60 |
| 2 | 98 | 126 | 77 | 236 | 135 | 70 | 169 | 59 |
| 3 | 106 | 122 | 90 | 224 | 130 | 68 | 165 | 62 |
從測試結(jié)果來看,Hutool提供的IoUtil、commons-io提供的IoUtil以及JDK1.7提供的NIO基于流方式耗時更優(yōu),但測試還應(yīng)參考內(nèi)存占用情況,具體可自行測試。
總結(jié)
到此這篇關(guān)于Java讀取文件的幾種方式的文章就介紹到這了,更多相關(guān)Java讀取文件方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用Java統(tǒng)計gitlab代碼行數(shù)
這篇文章主要介紹了如何使用Java統(tǒng)計gitlab代碼行數(shù),實現(xiàn)方式通過git腳本將所有的項目拉下來并然后通過進(jìn)行代碼行數(shù)的統(tǒng)計,需要的朋友可以參考下2023-10-10
springboot整合apache ftpserver詳細(xì)教程(推薦)
這篇文章主要介紹了springboot整合apache ftpserver詳細(xì)教程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01
Java類如何實現(xiàn)一個類的障眼法(JadClipse的bug)
這篇文章主要介紹了Java類實現(xiàn)一個類的障眼法(JadClipse的bug),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
Java中的MarkerFilter的應(yīng)用場景及使用示例詳解
這篇文章主要介紹了Java中的MarkerFilter的應(yīng)用場景及使用示例詳解,使用log4j2,負(fù)責(zé)從消息隊列收集日志的,現(xiàn)在系統(tǒng)收集到的日志能和這個系統(tǒng)本身的日志分開,需要的朋友可以參考下2024-01-01

