黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國(guó)咨詢/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學(xué)習(xí)攻略 Java學(xué)習(xí) 教你Java如何讀取文件

教你Java如何讀取文件

更新時(shí)間:2022-10-31 10:32:44 來源:動(dòng)力節(jié)點(diǎn) 瀏覽6014次

在本教程中,我們將探索從 Java 中讀取文件的不同方法。

首先,我們將學(xué)習(xí)如何從類路徑、URL 或使用標(biāo)準(zhǔn) Java 類的 JAR 文件加載文件。

其次,我們將了解如何使用 BufferedReader、Scanner、StreamTokenizer、DataInputStream、SequenceInputStream和FileChannel讀取內(nèi)容。我們還將討論如何讀取 UTF-8 編碼文件。

最后,我們將探索在 Java 7 和 Java 8 中加載和讀取文件的新技術(shù)。

設(shè)置

1.輸入文件

在本文的大多數(shù)示例中,我們將讀取一個(gè)文件名為 fileTest.txt的文本文件,其中包含一行:

Hello, world!

對(duì)于一些示例,我們將使用不同的文件;在這些情況下,我們將明確提及文件及其內(nèi)容。

2.輔助方法

我們將使用一組僅包含核心 Java 類的測(cè)試示例,在測(cè)試中,我們將使用帶有Hamcrest匹配器的斷言。

測(cè)試將共享一個(gè)通用的readFromInputStream方法,該方法將InputStream轉(zhuǎn)換為String以便更輕松地?cái)嘌越Y(jié)果:

private String readFromInputStream(InputStream inputStream)
  throws IOException {
    StringBuilder resultStringBuilder = new StringBuilder();
    try (BufferedReader br
      = new BufferedReader(new InputStreamReader(inputStream))) {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
        }
    }
  return resultStringBuilder.toString();
}

請(qǐng)注意,還有其他方法可以實(shí)現(xiàn)相同的結(jié)果。

從類路徑中讀取文件

1.使用標(biāo)準(zhǔn) Java

本節(jié)說明如何讀取類路徑中可用的文件。我們將閱讀src/main/resources下的“ fileTest.txt ” :

@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
    String expectedData = "Hello, world!";   
    Class clazz = FileOperationsTest.class;
    InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
    String data = readFromInputStream(inputStream);
    Assert.assertThat(data, containsString(expectedData));
}

在上面的代碼片段中,我們使用當(dāng)前類使用getResourceAsStream方法加載文件,并傳遞要加載的文件的絕對(duì)路徑。

ClassLoader實(shí)例也可以使用相同的方法:

ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
String data = readFromInputStream(inputStream);

我們使用getClass().getClassLoader()獲取當(dāng)前類的類加載器。

主要區(qū)別在于,在ClassLoader實(shí)例上使用getResourceAsStream時(shí),路徑被視為從類路徑的根開始的絕對(duì)路徑。

當(dāng)用于Class instance時(shí),路徑可以是相對(duì)于包的路徑,也可以是絕對(duì)路徑,由前導(dǎo)斜杠暗示。

當(dāng)然,請(qǐng)注意,在實(shí)踐中,打開的流應(yīng)該始終是關(guān)閉的,例如我們示例中的InputStream :

InputStream inputStream = null;
try {
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    inputStream = new FileInputStream(file);    
    //...
}     
finally {
    if (inputStream != null) {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.使用commons-io庫

另一個(gè)常見的選項(xiàng)是使用commons-io包的FileUtils類:

@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
    String expectedData = "Hello, world!";        
    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    String data = FileUtils.readFileToString(file, "UTF-8");        
    assertEquals(expectedData, data.trim());
}

這里我們將File對(duì)象傳遞給FileUtils類的readFileToString()方法。該實(shí)用程序類管理加載內(nèi)容,而無需編寫任何樣板代碼來創(chuàng)建InputStream實(shí)例并讀取數(shù)據(jù)。

同一個(gè)庫還提供IOUtils 類:

@Test
public void givenFileName_whenUsingIOUtils_thenFileData() {
    String expectedData = "Hello, world!";        
    FileInputStream fis = new FileInputStream("src/test/resources/fileTest.txt");
    String data = IOUtils.toString(fis, "UTF-8");        
    assertEquals(expectedData, data.trim());
}

里我們將FileInputStream對(duì)象傳遞給IOUtils類的toString()方法。此實(shí)用程序類的行為與前一個(gè)相同,以創(chuàng)建InputStream實(shí)例并讀取數(shù)據(jù)。

使用BufferedReader讀取

現(xiàn)在讓我們關(guān)注解析文件內(nèi)容的不同方法。

我們將從使用BufferedReader 讀取文件的簡(jiǎn)單方法開始:

@Test
public void whenReadWithBufferedReader_thenCorrect()
  throws IOException {
     String expected_value = "Hello, world!";
     String file ="src/test/resources/fileTest.txt";     
     BufferedReader reader = new BufferedReader(new FileReader(file));
     String currentLine = reader.readLine();
     reader.close();
    assertEquals(expected_value, currentLine);
}

請(qǐng)注意,當(dāng)?shù)竭_(dá)文件末尾時(shí), readLine()將返回null 。

使用 Java NIO 從文件中讀取

在 JDK7 中,NIO 包進(jìn)行了重大更新。

讓我們看一個(gè)使用Files類和readAllLines 方法的示例。readAllLines方法 接受一個(gè)路徑。

Path類可以被認(rèn)為是對(duì)java.io.File的升級(jí),其中包含一些額外的操作。

1.讀取小文件

以下代碼顯示了如何使用新的Files類讀取小文件:

@Test
public void whenReadSmallFileJava7_thenCorrect()
  throws IOException {
    String expected_value = "Hello, world!";
    Path path = Paths.get("src/test/resources/fileTest.txt");
    String read = Files.readAllLines(path).get(0);
    assertEquals(expected_value, read);
}

請(qǐng)注意,如果我們需要二進(jìn)制數(shù)據(jù),我們也可以使用readAllBytes()方法。

2.讀取大文件

如果我們想用Files類讀取一個(gè)大文件,我們可以使用BufferedReader。

以下代碼使用新的Files類和BufferedReader讀取文件:

@Test
public void whenReadLargeFileJava7_thenCorrect()
  throws IOException {
    String expected_value = "Hello, world!";
    Path path = Paths.get("src/test/resources/fileTest.txt");
    BufferedReader reader = Files.newBufferedReader(path);
    String line = reader.readLine();
    assertEquals(expected_value, line);
}

3.使用Files.lines()讀取文件

JDK8在Files類中提供了lines()方法。它返回一個(gè)字符串元素流。

讓我們看一個(gè)如何將數(shù)據(jù)讀入字節(jié)并使用 UTF-8 字符集對(duì)其進(jìn)行解碼的示例。

以下代碼使用 new Files.lines()讀取文件:

@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
    String expectedData = "Hello, world!";         
    Path path = Paths.get(getClass().getClassLoader()
      .getResource("fileTest.txt").toURI());         
    Stream<String> lines = Files.lines(path);
    String data = lines.collect(Collectors.joining("\n"));
    lines.close();         
    Assert.assertEquals(expectedData, data.trim());
}

將 Stream 與文件操作等 IO 通道一起使用,我們需要使用 close()方法顯式關(guān)閉流。

正如我們所見,F(xiàn)iles API 提供了另一種將文件內(nèi)容讀入字符串的簡(jiǎn)單方法。

在接下來的部分中,我們將了解其他不太常見的讀取文件的方法,這些方法在某些情況下可能是合適的。

用掃描儀閱讀

接下來讓我們使用掃描儀從文件中讀取。在這里,我們將使用空格作為分隔符:

@Test
public void whenReadWithScanner_thenCorrect()
  throws IOException {
    String file = "src/test/resources/fileTest.txt";
    Scanner scanner = new Scanner(new File(file));
    scanner.useDelimiter(" ");
    assertTrue(scanner.hasNext());
    assertEquals("Hello,", scanner.next());
    assertEquals("world!", scanner.next());
    scanner.close();
}

請(qǐng)注意,默認(rèn)分隔符是空格,但多個(gè)分隔符可以與Scanner一起使用。

Scanner類在從控制臺(tái)讀取內(nèi)容時(shí)很有用,或者當(dāng)內(nèi)容包含帶有已知分隔符的原始值(例如:用空格分隔的整數(shù)列表)時(shí)。

使用StreamTokenizer讀取

現(xiàn)在讓我們使用StreamTokenizer將文本文件讀入令牌。

標(biāo)記器首先確定下一個(gè)標(biāo)記是什么,字符串或數(shù)字。我們通過查看tokenizer.ttype 字段來做到這一點(diǎn)。

然后我們將根據(jù)這種類型讀取實(shí)際的令牌:

tokenizer.nval – 如果類型是數(shù)字

tokenizer.sval – 如果類型是字符串

在這個(gè)例子中,我們將使用一個(gè)不同的輸入文件,它只包含:

Hello 1

以下代碼從文件中讀取字符串和數(shù)字:

@Test
public void whenReadWithStreamTokenizer_thenCorrectTokens()
  throws IOException {
    String file = "src/test/resources/fileTestTokenizer.txt";
   FileReader reader = new FileReader(file);
    StreamTokenizer tokenizer = new StreamTokenizer(reader);
    // token 1
    tokenizer.nextToken();
    assertEquals(StreamTokenizer.TT_WORD, tokenizer.ttype);
    assertEquals("Hello", tokenizer.sval);
    // token 2    
    tokenizer.nextToken();
    assertEquals(StreamTokenizer.TT_NUMBER, tokenizer.ttype);
    assertEquals(1, tokenizer.nval, 0.0000001);
    // token 3
    tokenizer.nextToken();
    assertEquals(StreamTokenizer.TT_EOF, tokenizer.ttype);
    reader.close();
}

請(qǐng)注意最后如何使用文件結(jié)束標(biāo)記。

這種方法對(duì)于將輸入流解析為標(biāo)記很有用。

使用DataInputStream讀取

我們可以使用DataInputStream從文件中讀取二進(jìn)制或原始數(shù)據(jù)類型。

以下測(cè)試使用DataInputStream讀取文件:

@Test
public void whenReadWithDataInputStream_thenCorrect() throws IOException {
    String expectedValue = "Hello, world!";
    String file ="src/test/resources/fileTest.txt";
    String result = null;
    DataInputStream reader = new DataInputStream(new FileInputStream(file));
    int nBytesToRead = reader.available();
    if(nBytesToRead > 0) {
        byte[] bytes = new byte[nBytesToRead];
        reader.read(bytes);
        result = new String(bytes);
    }
    assertEquals(expectedValue, result);
}

使用FileChannel讀取

如果我們正在讀取一個(gè)大文件,F(xiàn)ileChannel可以比標(biāo)準(zhǔn) IO 更快。

以下代碼使用FileChannel和RandomAccessFile從文件中讀取數(shù)據(jù)字節(jié):

@Test
public void whenReadWithFileChannel_thenCorrect()
  throws IOException {
    String expected_value = "Hello, world!";
    String file = "src/test/resources/fileTest.txt";
    RandomAccessFile reader = new RandomAccessFile(file, "r");
    FileChannel channel = reader.getChannel();
    int bufferSize = 1024;
    if (bufferSize > channel.size()) {
        bufferSize = (int) channel.size();
    }
    ByteBuffer buff = ByteBuffer.allocate(bufferSize);
    channel.read(buff);
    buff.flip();    
    assertEquals(expected_value, new String(buff.array()));
    channel.close();
    reader.close();
}

讀取 UTF-8 編碼文件

現(xiàn)在讓我們看看如何使用BufferedReader 讀取 UTF-8 編碼的文件。在這個(gè)例子中,我們將讀取一個(gè)包含中文字符的文件:

@Test
public void whenReadUTFEncodedFile_thenCorrect()
  throws IOException {
    String expected_value = "青空";
    String file = "src/test/resources/fileTestUtf8.txt";
    BufferedReader reader = new BufferedReader
      (new InputStreamReader(new FileInputStream(file), "UTF-8"));
    String currentLine = reader.readLine();
    reader.close();
    assertEquals(expected_value, currentLine);
}

從 URL 讀取內(nèi)容

要從 URL 讀取內(nèi)容,我們將在示例中使用“ / ” URL:

@Test
public void givenURLName_whenUsingURL_thenFileData() {
    String expectedData = "Baeldung";
    URL urlObject = new URL("/");
    URLConnection urlConnection = urlObject.openConnection();
    InputStream inputStream = urlConnection.getInputStream();
    String data = readFromInputStream(inputStream);
    Assert.assertThat(data, containsString(expectedData));
}

還有其他連接到 URL 的方法。在這里,我們使用了標(biāo)準(zhǔn) SDK 中可用的URL和URLConnection類。

從 JAR 中讀取文件

要讀取位于 JAR 文件中的文件,我們需要一個(gè)包含文件的 JAR。對(duì)于我們的示例,我們將從“ hamcrest-library-1.3.jar ”文件中讀取“ LICENSE.txt ”:

@Test
public void givenFileName_whenUsingJarFile_thenFileData() {
    String expectedData = "BSD License";
    Class clazz = Matchers.class;
    InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
    String data = readFromInputStream(inputStream);
    Assert.assertThat(data, containsString(expectedData));
}

在這里,我們要加載位于 Hamcrest 庫中的LICENSE.txt ,因此我們將使用有助于獲取資源的Matcher類。也可以使用類加載器加載相同的文件。如果大家想了解更多相關(guān)知識(shí),不妨來關(guān)注一下本站的Java在線學(xué)習(xí),里面的課程內(nèi)容細(xì)致全面,很適合沒有基礎(chǔ)的小伙伴學(xué)習(xí),希望對(duì)大家能夠有所幫助哦。

提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)

  • 全國(guó)校區(qū) 2025-05-15 搶座中
  • 全國(guó)校區(qū) 2025-06-05 搶座中
  • 全國(guó)校區(qū) 2025-06-26 搶座中
免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 久久亚洲精品视频 | 最近中文字幕大全高清视频 | 伊人热热久久原色播放www | 日本边添边摸边做边爱小视频 | 亚洲 欧美 成人日韩 | 国产三级日本三级在线播放 | 欧美综合中文字幕久久 | 国产精品1| 亚洲黄色片免费看 | 69av导航| 五月天综合婷婷 | 播五月综合| 欧美一区二区三区免费播放 | 国产午夜剧场 | 一级毛片女人喷潮 | 久久这里精品青草免费 | 日日碰狠狠添天天爽 | 午夜 dy888理论久久 | 免费日韩 | 91免费网 | 国亚洲欧美日韩精品 | 神马午夜嘿嘿嘿 | 亚洲国产二区三区 | 国产丝袜视频在线观看 | 黄色网址最新 | 色综合久久天天综合绕观看 | 看黄色特级片 | 精品久久天干天天天按摩 | 亚洲国产欧美另类 | 成人18毛片 | 欧美精品亚洲精品日韩 | 欧美一区日韩精品 | 黄色私人影院 | 一个人免费观看视频www | 亚洲va欧美va国产综合久久 | 精品剧情v国产在线麻豆 | 交video | 小明天天看成人免费看 | 亚欧毛片基地国产毛片基地 | 91视频首页 | 亚洲超大尺度激情啪啪人体 |