java?io文件操作從文件讀取數(shù)據(jù)的六種方法
在上一篇文章中,我為大家介紹了《5種創(chuàng)建文件并寫入文件數(shù)據(jù)的方法》,本節(jié)我們?yōu)榇蠹襾斫榻B6種從文件中讀取數(shù)據(jù)的方法.
另外為了方便大家理解,我為這一篇文章錄制了對應(yīng)的視頻:總結(jié)java從文件中讀取數(shù)據(jù)的6種方法-JAVA IO基礎(chǔ)總結(jié)第二篇
Scanner
(Java 1.5) 按行讀數(shù)據(jù)及String、Int類型等按分隔符讀數(shù)據(jù)。
Files.lines
, 返回Stream(Java 8) 流式數(shù)據(jù)處理,按行讀取
Files.readAllLines
, 返回List<String>(Java 8)
Files.readString
, 讀取String(Java 11), 文件最大 2G.
Files.readAllBytes
, 讀取byte[](Java 7), 文件最大 2G.
BufferedReader
, 經(jīng)典方式 (Java 1.1 -> forever)
可以說,每一種方法都有自己的適用場景,下文中為大家來一一介紹。
1.Scanner
第一種方式是Scanner,從JDK1.5開始提供的API,特點是可以按行讀取、按分割符去讀取文件數(shù)據(jù),既可以讀取String類型,也可以讀取Int類型、Long類型等基礎(chǔ)數(shù)據(jù)類型的數(shù)據(jù)。
@Test void testReadFile1() throws IOException { //文件內(nèi)容: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() 、基礎(chǔ)數(shù)據(jù)類型等等等等。 //文件內(nèi)容: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); } } }
上面的方法輸出結(jié)果如下:
Hello World|Hello Zimug
Hello World
Hello Zimug
1
2
2.Files.lines (Java 8)
如果你是需要按行去處理數(shù)據(jù)文件的內(nèi)容,這種方式是我推薦大家去使用的一種方式,代碼簡潔,使用java 8的Stream流將文件讀取與文件處理有機(jī)融合。
@Test void testReadFile2() throws IOException { String fileName = "D:\\data\\test\\newFile.txt"; // 讀取文件內(nèi)容到Stream流中,按行讀取 Stream<String> lines = Files.lines(Paths.get(fileName)); // 隨機(jī)行順序進(jìn)行數(shù)據(jù)處理 lines.forEach(ele -> { System.out.println(ele); }); }
forEach獲取Stream流中的行數(shù)據(jù)不能保證順序,但速度快。如果你想按順序去處理文件中的行數(shù)據(jù),可以使用forEachOrdered,但處理效率會下降。
// 按文件行順序進(jìn)行處理 lines.forEachOrdered(System.out::println);
或者利用CPU多和的能力,進(jìn)行數(shù)據(jù)的并行處理parallel(),適合比較大的文件。
// 按文件行順序進(jìn)行處理 lines.parallel().forEachOrdered(System.out::println);
也可以把Stream<String>
轉(zhuǎn)換成List<String>
,但是要注意這意味著你要將所有的數(shù)據(jù)一次性加載到內(nèi)存,要注意java.lang.OutOfMemoryError
// 轉(zhuǎn)換成List<String>, 要注意java.lang.OutOfMemoryError: Java heap space List<String> collect = lines.collect(Collectors.toList());
3.Files.readAllLines
這種方法仍然是java8 為我們提供的,如果我們不需要Stream<String>
,我們想直接按行讀取文件獲取到一個List<String>
,就采用下面的方法。同樣的問題:這意味著你要將所有的數(shù)據(jù)一次性加載到內(nèi)存,要注意java.lang.OutOfMemoryError
@Test void testReadFile3() throws IOException { String fileName = "D:\\data\\test\\newFile3.txt"; // 轉(zhuǎn)換成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,同時要注意你的服務(wù)器及JVM內(nèi)存。這種方法適合快速讀取小文本文件。
@Test void testReadFile4() throws IOException { String fileName = "D:\\data\\test\\newFile3.txt"; // java 11 開始提供的方法,讀取文件不能超過2G,與你的內(nèi)存息息相關(guān) //String s = Files.readString(Paths.get(fileName)); }
5.Files.readAllBytes()
如果你沒有JDK11(readAllBytes()始于JDK7),仍然想一次性的快速讀取一個文件的內(nèi)容轉(zhuǎn)為String,該怎么辦?先將數(shù)據(jù)讀取為二進(jìn)制數(shù)組,然后轉(zhuǎn)換成String內(nèi)容。這種方法適合在沒有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.經(jīng)典管道流的方式
最后一種就是經(jīng)典的管道流的方式
@Test void testReadFile6() throws IOException { String fileName = "D:\\data\\test\\newFile3.txt"; // 帶緩沖的流讀取,默認(rèn)緩沖區(qū)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就可以使用下面的代碼,前提是文件中的數(shù)據(jù)是ObjectOutputStream寫入的數(shù)據(jù),才可以用ObjectInputStream來讀取。
try (FileInputStream fis = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(fis)){ ois.readObject(); }
以上就是java io操作總結(jié)從文件讀取數(shù)據(jù)的六種方法的詳細(xì)內(nèi)容,更多關(guān)于java io從文件讀取數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java 高并發(fā)十: JDK8對并發(fā)的新支持詳解
本文主要介紹Java 高并發(fā)JDK8的支持,這里整理了詳細(xì)的資料及1. LongAdder 2. CompletableFuture 3. StampedLock的介紹,有興趣的小伙伴可以參考下2016-09-09詳解Java如何實現(xiàn)在PDF中插入,替換或刪除圖像
圖文并茂的內(nèi)容往往讓人看起來更加舒服,如果只是文字內(nèi)容的累加,往往會使讀者產(chǎn)生視覺疲勞。搭配精美的文章配圖則會使文章內(nèi)容更加豐富。那我們要如何在PDF中插入、替換或刪除圖像呢?別擔(dān)心,今天為大家介紹一種高效便捷的方法2023-01-01Java8內(nèi)存模型PermGen Metaspace實例解析
這篇文章主要介紹了Java8內(nèi)存模型PermGen Metaspace實例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03Mybatis的parameterType造成線程阻塞問題分析
這篇文章主要詳細(xì)分析了Mybatis的parameterType造成線程阻塞問題,文中有詳細(xì)的解決方法,及相關(guān)的代碼示例,具有一定的參考價值,感興趣的朋友可以借鑒閱讀2023-06-06JSP頁面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案
這篇文章主要介紹了JSP頁面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案,非常實用,需要的朋友可以參考下2014-08-08