在上一篇文章中,我為大家介紹了《5種建立檔案並寫入檔案資料的方法》,本節我們為大家來介紹6種從檔案中讀取資料的方法.
另外為了方便大家理解,我為這一篇文章錄製了對應的視訊:總結java從檔案中讀取資料的6種方法-JAVA IO基礎總結第二篇
Scanner
(Java 1.5) 按行讀資料及String、Int型別等按分隔符讀資料。Files.lines
, 返回Stream
(Java 8) 流式資料處理,按行讀取Files.readAllLines
, 返回List<String>
(Java 8)Files.readString
, 讀取String
(Java 11), 檔案最大 2G.Files.readAllBytes
, 讀取byte[]
(Java 7), 檔案最大 2G.BufferedReader
, 經典方式 (Java 1.1 -> forever)
可以說,每一種方法都有自己的適用場景,下文中為大家來一一介紹。
如果您看完我的創作,覺得您有幫助的話,請幫忙點贊,您的支援是我不竭的創作動力!
1.Scanner
第一種方式是Scanner,從JDK1.5開始提供的API,特點是可以按行讀取、按分割符去讀取檔案資料,既可以讀取String型別,也可以讀取Int型別、Long型別等基礎資料型別的資料。
@Test
void testReadFile1() throws IOException {
//檔案內容:Hello World|Hello Zimug
String fileName = "D:\\data\\test\\newFile4.txt";
try (Scanner sc = new Scanner(new FileReader(fileName))) {
while (sc.hasNextLine()) { //按行讀取字串
String line = sc.nextLine();
System.out.println(line);
}
}
try (Scanner sc = new Scanner(new FileReader(fileName))) {
sc.useDelimiter("\\|"); //分隔符
while (sc.hasNext()) { //按分隔符讀取字串
String str = sc.next();
System.out.println(str);
}
}
//sc.hasNextInt() 、hasNextFloat() 、基礎資料型別等等等等。
//檔案內容:1|2
fileName = "D:\\data\\test\\newFile5.txt";
try (Scanner sc = new Scanner(new FileReader(fileName))) {
sc.useDelimiter("\\|"); //分隔符
while (sc.hasNextInt()) { //按分隔符讀取Int
int intValue = sc.nextInt();
System.out.println(intValue);
}
}
}
上面的方法輸出結果如下:
Hello World|Hello Zimug
Hello World
Hello Zimug
1
2
2.Files.lines (Java 8)
如果你是需要按行去處理資料檔案的內容,這種方式是我推薦大家去使用的一種方式,程式碼簡潔,使用java 8的Stream流將檔案讀取與檔案處理有機融合。
@Test
void testReadFile2() throws IOException {
String fileName = "D:\\data\\test\\newFile.txt";
// 讀取檔案內容到Stream流中,按行讀取
Stream<String> lines = Files.lines(Paths.get(fileName));
// 隨機行順序進行資料處理
lines.forEach(ele -> {
System.out.println(ele);
});
}
forEach獲取Stream流中的行資料不能保證順序,但速度快。如果你想按順序去處理檔案中的行資料,可以使用forEachOrdered,但處理效率會下降。
// 按檔案行順序進行處理
lines.forEachOrdered(System.out::println);
或者利用CPU多和的能力,進行資料的並行處理parallel(),適合比較大的檔案。
// 按檔案行順序進行處理
lines.parallel().forEachOrdered(System.out::println);
也可以把Stream<String>
轉換成List<String>
,但是要注意這意味著你要將所有的資料一次性載入到記憶體,要注意java.lang.OutOfMemoryError
// 轉換成List<String>, 要注意java.lang.OutOfMemoryError: Java heap space
List<String> collect = lines.collect(Collectors.toList());
3.Files.readAllLines
這種方法仍然是java8 為我們提供的,如果我們不需要Stream<String>
,我們想直接按行讀取檔案獲取到一個List<String>
,就採用下面的方法。同樣的問題:這意味著你要將所有的資料一次性載入到記憶體,要注意java.lang.OutOfMemoryError
@Test
void testReadFile3() throws IOException {
String fileName = "D:\\data\\test\\newFile3.txt";
// 轉換成List<String>, 要注意java.lang.OutOfMemoryError: Java heap space
List<String> lines = Files.readAllLines(Paths.get(fileName),
StandardCharsets.UTF_8);
lines.forEach(System.out::println);
}
4.Files.readString(JDK 11)
從 java11開始,為我們提供了一次性讀取一個檔案的方法。檔案不能超過2G,同時要注意你的伺服器及JVM記憶體。這種方法適合快速讀取小文字檔案。
@Test
void testReadFile4() throws IOException {
String fileName = "D:\\data\\test\\newFile3.txt";
// java 11 開始提供的方法,讀取檔案不能超過2G,與你的記憶體息息相關
//String s = Files.readString(Paths.get(fileName));
}
5.Files.readAllBytes()
如果你沒有JDK11(readAllBytes()始於JDK7),仍然想一次性的快速讀取一個檔案的內容轉為String,該怎麼辦?先將資料讀取為二進位制陣列,然後轉換成String內容。這種方法適合在沒有JDK11的請開給你下,快速讀取小文字檔案。
@Test
void testReadFile5() throws IOException {
String fileName = "D:\\data\\test\\newFile3.txt";
//如果是JDK11用上面的方法,如果不是用這個方法也很容易
byte[] bytes = Files.readAllBytes(Paths.get(fileName));
String content = new String(bytes, StandardCharsets.UTF_8);
System.out.println(content);
}
6.經典管道流的方式
最後一種就是經典的管道流的方式
@Test
void testReadFile6() throws IOException {
String fileName = "D:\\data\\test\\newFile3.txt";
// 帶緩衝的流讀取,預設緩衝區8k
try (BufferedReader br = new BufferedReader(new FileReader(fileName))){
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
//java 8中這樣寫也可以
try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName))){
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
這種方式可以通過管道流巢狀的方式,組合使用,比較靈活。比如我們
想從檔案中讀取java Object就可以使用下面的程式碼,前提是檔案中的資料是ObjectOutputStream寫入的資料,才可以用ObjectInputStream來讀取。
try (FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis)){
ois.readObject();
}
歡迎關注我的部落格,裡面有很多精品合集
- 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格。
覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。