Java - ファイルから読み込む

Java –ファイルから読み取る

1. 概要

このチュートリアルでは、read from a File in Javaのさまざまな方法について説明します。 BufferedReaderScannerStreamTokenizerDataInputStreamSequenceInputStreamFileChannelを使用します。

次に、UTF-8でエンコードされたファイルの読み取り方法と、ファイルのコンテンツから文字列を作成する方法について説明します。

最後に、Java 7のファイルから読み取るための新しい手法を探ります。

この記事は、例としてここのthe “Java – Back to Basic” seriesの一部です。

2. BufferedReaderで読み取る

BufferedReaderを使用してファイルから読み取る簡単な方法から始めましょう。ファイル自体には次のものが含まれます。

Hello world

次のコードは、BufferedReaderを使用してファイルから読み取ります。

@Test
public void whenReadWithBufferedReader_thenCorrect()
  throws IOException {
     String expected_value = "Hello world";
     String file ="src/test/resources/test_read.txt";

     BufferedReader reader = new BufferedReader(new FileReader(file));
     String currentLine = reader.readLine();
     reader.close();

    assertEquals(expected_value, currentLine);
}

ファイルの終わりに達すると、readLine()nullを返すことに注意してください。

3. Scannerで読み取る

次に、Scannerを使用してファイルから読み取ります。ファイルには次のものが含まれています。

Hello world 1

区切り文字として単純な空白を使用します。

@Test
public void whenReadWithScanner_thenCorrect()
  throws IOException {
    String file = "src/test/resources/test_read.txt";
    Scanner scanner = new Scanner(new File(file));
    scanner.useDelimiter(" ");

    assertTrue(scanner.hasNext());
    assertEquals("Hello", scanner.next());
    assertEquals("world", scanner.next());
    assertEquals(1, scanner.nextInt());

    scanner.close();
}

デフォルトの区切り文字は空白ですが、Scannerで複数の区切り文字を使用できることに注意してください。

4. StreamTokenizerで読み取る

次に、StreamTokenizerを使用してテキストファイルをトークンに読み込みます。

トークナイザーの仕組みは次のとおりです–まず、次のトークンが何であるかを理解する必要があります–文字列または数字。これを行うには、tokenizer.ttypeフィールドを確認します。

次に、このタイプに基づいて実際のトークンを読み取ります。

  • tokenizer.nval –タイプが数値の場合

  • tokenizer.sval –タイプが文字列の場合

ファイルには、単純に含まれています:

Hello 1

次のコードは、ファイルから文字列と数値の両方を読み取ります。

@Test
public void whenReadWithStreamTokenizer_thenCorrectTokens()
  throws IOException {
    String file = "src/test/resources/test_read.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();
}

最後にファイルの終わりトークンがどのように使用されるかに注意してください。

5. DataInputStreamで読み取る

DataInputStreamを使用して、ファイルからバイナリまたはプリミティブデータ型を読み取ることができます。

実際のファイル自体から始めましょう。

Hello

次のテストでは、DataInputStreamを使用してファイルを読み取ります。

@Test
public void whenReadWithDataInputStream_thenCorrect()
  throws IOException {
    String expectedValue = "Hello";
    String file ="src/test/resources/test_read.txt";
    DataInputStream reader = new DataInputStream(new FileInputStream(file));
    String result = reader.readUTF();
    reader.close();

    assertEquals(expectedValue, result);
}

6. FileChannelで読み取る

大きなファイルを読み取る場合、FileChannelは標準IOよりも高速になる可能性があります。

ファイルの内容

 Hello world

次のコードは、FileChannelRandomAccessFileを使用してファイルからデータバイトを読み取ります。

@Test
public void whenReadWithFileChannel_thenCorrect()
  throws IOException {
    String expected_value = "Hello world";
    String file = "src/test/resources/test_read.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();
}

7. UTF-8エンコードファイルを読む

それでは、BufferedReaderを使用してUTF-8でエンコードされたファイルを読み取る方法を見てみましょう。

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

    assertEquals(expected_value, currentLine);
}

8. ファイルを文字列に読み込む

StringBuilderからread the entire contents of a file into a Stringをうまく利用できます。 ファイルから始めましょう:

Hello world

Test line

次のコードは、ファイルから読み取ったデータを1行ずつStringBuilderに追加します。

@Test
public void whenReadFileContentsIntoString_thenCorrect()
  throws IOException {
    String expected_value = "Hello world n Test line n";
    String file = "src/test/resources/test_read.txt";
    BufferedReader reader = new BufferedReader(new FileReader(file));
    StringBuilder builder = new StringBuilder();
    String currentLine = reader.readLine();
    while (currentLine != null) {
        builder.append(currentLine);
        builder.append("n");
        currentLine = reader.readLine();
    }

    reader.close();
    assertEquals(expected_value, builder.toString());
}

9. Java7を使用してファイルから読み取る

Java 7では、ファイルとファイルシステムを操作する新しい方法が導入されています。それを利用してファイルを読み取りましょう。

9.1. Java7で小さなファイルを読む

ファイルの内容

 Hello world

次のコードは、新しいFilesクラスを使用して小さなファイルを読み取る方法を示しています。

@Test
public void whenReadSmallFileJava7_thenCorrect()
  throws IOException {
    String expected_value = "Hello world";

    Path path = Paths.get("src/test/resources/test_read.txt");

    String read = Files.readAllLines(path).get(0);
    assertEquals(expected_value, read);
}

バイナリデータが必要な場合は、readAllBytes()メソッドも使用できることに注意してください。

9.2. Java7で大きなファイルを読む

Filesクラスの大きなファイルを読み取りたい場合は、BufferedReaderを使用できます。

ファイルの内容

 Hello world

次のコードは、新しいFilesクラスとBufferedReaderを使用してファイルを読み取ります。

@Test
public void whenReadLargeFileJava7_thenCorrect()
  throws IOException {
    String expected_value = "Hello world";

    Path path = Paths.get("src/test/resources/test_read.txt");

    BufferedReader reader = Files.newBufferedReader(path);
    String line = reader.readLine();
    assertEquals(expected_value, line);
}

10. 結論

ご覧のとおり、プレーンJavaを使用してファイルからデータを読み取る多くの可能性があります。 BufferedReaderで行ごとに読み取り、Scannerで異なる区切り文字を使用して読み取り、StreamTokenizerでファイルをトークンに読み取り、DataInputStreamでバイナリデータとプリミティブデータを読み取ることができます。タイプ、複数のファイルを1つのストリームにリンクするためのSequenceInput Stream、大きなファイルからより高速に読み取るためのFileChannelなど。