Java:テキストファイルの読み方


81

スペースで区切られた値を含むテキストファイルを読みたい。値は整数です。どうすればそれを読み取って配列リストに入れることができますか?

テキストファイルの内容の例を次に示します。

1 62 4 55 5 6 77

としてarraylistに入れたいです[1, 62, 4, 55, 5, 6, 77]。Javaでそれを行うにはどうすればよいですか?

回答:


170

を使用Files#readAllLines()して、テキストファイルのすべての行をに入れることができますList<String>

for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
    // ...
}

チュートリアル:基本I / O>ファイルI / O>テキストファイルの読み取り、書き込み、作成


を使用String#split()Stringて、正規表現に基づいてをパーツに分割できます。

for (String part : line.split("\\s+")) {
    // ...
}

チュートリアル:数字と文字列>文字列>文字列内の文字の操作


あなたは使用することができますInteger#valueOf()変換することStringInteger

Integer i = Integer.valueOf(part);

チュートリアル:数値と文字列>文字列>数値と文字列間の変換


List#add()要素を追加するために使用できますList

numbers.add(i);

チュートリアル:インターフェース>リストインターフェース


つまり、一言で言えば(ファイルに空の行や末尾/先頭の空白がないと仮定)。

List<Integer> numbers = new ArrayList<>();
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
    for (String part : line.split("\\s+")) {
        Integer i = Integer.valueOf(part);
        numbers.add(i);
    }
}

すでにJava8を使用している場合は、Files#lines()。で始まるStreamAPIを使用することもできます。

List<Integer> numbers = Files.lines(Paths.get("/path/to/test.txt"))
    .map(line -> line.split("\\s+")).flatMap(Arrays::stream)
    .map(Integer::valueOf)
    .collect(Collectors.toList());

チュートリアル:Java8ストリームを使用したデータの処理


1
Java 7および8でこれを行うためのより良い方法があることに注意してください:stackoverflow.com/questions/4716503
Alex Beardsley

34

Java 1.5では、ファイルおよびストリームからの入力を処理するためのScannerクラスが導入されました。

これはファイルから整数を取得するために使用され、次のようになります。

List<Integer> integers = new ArrayList<Integer>();
Scanner fileScanner = new Scanner(new File("c:\\file.txt"));
while (fileScanner.hasNextInt()){
   integers.add(fileScanner.nextInt());
}

ただし、APIを確認してください。さまざまなタイプの入力ソース、さまざまな区切り文字、さまざまなデータタイプを処理するためのオプションは他にもたくさんあります。


2
これは、バッファリングされたioリーダーの組み合わせよりもはるかに覚えやすいです
avanderw 2014年

18

このサンプルコードは、Javaでファイルを読み取る方法を示しています。

import java.io.*;

/**
 * This example code shows you how to read file in Java
 *
 * IN MY CASE RAILWAY IS MY TEXT FILE WHICH I WANT TO DISPLAY YOU CHANGE WITH YOUR   OWN      
 */

 public class ReadFileExample 
 {
    public static void main(String[] args) 
    {
       System.out.println("Reading File from Java code");
       //Name of the file
       String fileName="RAILWAY.txt";
       try{

          //Create object of FileReader
          FileReader inputFile = new FileReader(fileName);

          //Instantiate the BufferedReader Class
          BufferedReader bufferReader = new BufferedReader(inputFile);

          //Variable to hold the one line data
          String line;

          // Read file line by line and print on the console
          while ((line = bufferReader.readLine()) != null)   {
            System.out.println(line);
          }
          //Close the buffer reader
          bufferReader.close();
       }catch(Exception e){
          System.out.println("Error while reading file line by line:" + e.getMessage());                      
       }

     }
  }

10

この例を見て、自分でやってみてください。

import java.io.*;

public class ReadFile {

    public static void main(String[] args){
        String string = "";
        String file = "textFile.txt";

        // Reading
        try{
            InputStream ips = new FileInputStream(file);
            InputStreamReader ipsr = new InputStreamReader(ips);
            BufferedReader br = new BufferedReader(ipsr);
            String line;
            while ((line = br.readLine()) != null){
                System.out.println(line);
                string += line + "\n";
            }
            br.close();
        }
        catch (Exception e){
            System.out.println(e.toString());
        }

        // Writing
        try {
            FileWriter fw = new FileWriter (file);
            BufferedWriter bw = new BufferedWriter (fw);
            PrintWriter fileOut = new PrintWriter (bw);
                fileOut.println (string+"\n test of read and write !!");
            fileOut.close();
            System.out.println("the file " + file + " is created!");
        }
        catch (Exception e){
            System.out.println(e.toString());
        }
    }
}

5

楽しみのために、これが実際のプロジェクトでおそらく行うことです。ここでは、お気に入りのライブラリ(この場合はGuava、以前はGoogleコレクションとして知られていました)をすべて使用しています。

String text = Files.toString(new File("textfile.txt"), Charsets.UTF_8);
List<Integer> list = Lists.newArrayList();
for (String s : text.split("\\s")) {
    list.add(Integer.valueOf(s));
}

利点:維持する独自のコードはあまりありません(たとえば、これとは対照的です)。編集:この場合、tschaibleのスキャナーソリューションにはこれ以上コードがないことに注意してください!

欠点:このためだけに新しいライブラリの依存関係を追加したくない場合があります。(それなら、プロジェクトでグアバを利用しないのはばかげているでしょう。;-)


もちろん、ループの代わりにGoogleコレクションのtransform()と関数を使用することもできますが、IMHOは読みにくく、さらに短くはなりません。
Jonik 2010年

4

このような単純な/一般的なものには、Apache Commons(IOおよびLang)を使用します。

輸入:

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;

コード:

String contents = FileUtils.readFileToString(new File("path/to/your/file.txt"));
String[] array = ArrayUtils.toArray(contents.split(" "));

完了。


2

Java7を使用してNIO.2でファイルを読み取る

これらのパッケージをインポートします。

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

これは、ファイルを読み取るプロセスです。

Path file = Paths.get("C:\\Java\\file.txt");

if(Files.exists(file) && Files.isReadable(file)) {

    try {
        // File reader
        BufferedReader reader = Files.newBufferedReader(file, Charset.defaultCharset());

        String line;
        // read each line
        while((line = reader.readLine()) != null) {
            System.out.println(line);
            // tokenize each number
            StringTokenizer tokenizer = new StringTokenizer(line, " ");
            while (tokenizer.hasMoreElements()) {
                // parse each integer in file
                int element = Integer.parseInt(tokenizer.nextToken());
            }
        }
        reader.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

ファイルのすべての行を一度に読み取るには:

Path file = Paths.get("C:\\Java\\file.txt");
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);

1

これまでに与えられたすべての答えは、ファイルを1行ずつ読み取り、その行をとして取り込んStringでから、を処理することを含みますString

これが最も理解しやすいアプローチであることは間違いありません。ファイルがかなり短い場合(たとえば、数万行)、効率の観点からも許容できます。ただし、ファイルが長い場合は、次の2つの理由から、非常に非効率的な方法です。

  1. すべての文字は2回処理されます。1回はの作成、Stringもう1回は処理です。
  2. ファイルに多くの行がある場合、ガベージコレクターは友達にはなりません。String行ごとに新しいものを作成し、次の行に移動するときにそれを破棄します。ガベージコレクターは、最終的には、不要になったこれらすべてのStringオブジェクトを破棄する必要があります。誰かがあなたの後片付けをしなければなりません。

速度が気になる場合は、データのブロックを読み取ってから、行ごとではなくバイトごとに処理する方がはるかに優れています。あなたが数の終わりに来るたびに、Listあなたはあなたが構築しているものにそれを追加します。

次のようになります。

private List<Integer> readIntegers(File file) throws IOException {
    List<Integer> result = new ArrayList<>();
    RandomAccessFile raf = new RandomAccessFile(file, "r");
    byte buf[] = new byte[16 * 1024];
    final FileChannel ch = raf.getChannel();
    int fileLength = (int) ch.size();
    final MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0,
            fileLength);
    int acc = 0;
    while (mb.hasRemaining()) {
        int len = Math.min(mb.remaining(), buf.length);
        mb.get(buf, 0, len);
        for (int i = 0; i < len; i++)
            if ((buf[i] >= 48) && (buf[i] <= 57))
                acc = acc * 10 + buf[i] - 48;
            else {
                result.add(acc);
                acc = 0;
            }
    }
    ch.close();
    raf.close();
    return result;
}

上記のコードは、これがASCIIであり(他のエンコーディング用に簡単に調整できる場合もあります)、数字以外のもの(特に、スペースまたは改行)が数字間の境界を表すことを前提としています。また、ファイルが数字以外で終わることも前提としています(実際には、最後の行が改行で終わることを前提としています)が、そうでない場合に対処するために微調整することもできます。

これは、この質問への回答として提供されているベースのアプローチよりはるかに高速ですStringこの質問には、非常によく似た問題の詳細な調査があります。マルチスレッドラインを下げたい場合は、さらに改善できる可能性があることがわかります。


0

ファイルを読み取り、必要な操作を実行しますjava8 Files.lines(Paths.get( "c://lines.txt"))。collect(Collectors.toList());

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.