スペースで区切られた値を含むテキストファイルを読みたいです。値は整数です。それを読んでそれを配列リストに入れるにはどうすればいいですか?
テキストファイルの内容の例を次に示します。
1 62 4 55 5 6 77
私は[1, 62, 4, 55, 5, 6, 77]
としてそれをアレイリストに入れたいのです。どうすればJavaでそれをすることができますか?
テキストファイルのすべての行をList<String>
にするには、 Files#readAllLines()
を使用できます。
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
// ...
}
チュートリアル: 基本入出力>ファイル入出力>テキストファイルの読み取り、書き込み、作成
String#split()
を使用すると、正規表現に基づいてString
を分割することができます。
for (String part : line.split("\\s+")) {
// ...
}
チュートリアル: 数字と文字列>文字列>文字列内の文字の操作
String
をInteger
に変換するには、 Integer#valueOf()
を使用できます。
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);
}
}
すでにJava 8に慣れている場合は、 Files#lines()
から始めて、 Stream API を使用することもできます。
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());
チュートリアル: Java 8ストリームでデータを処理する
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を確認してください。さまざまな種類の入力ソース、さまざまな区切り文字、さまざまなデータ型を処理するためのオプションが他にもたくさんあります。
このコード例は、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());
}
}
}
この例を見て、自分でやってみてください。
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());
}
}
}
楽しみのために、ここで私はおそらく私がすでに私のお気に入りのライブラリをすべて使っている本物のプロジェクトでやるべきことがある(この場合 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));
}
利点:維持するコードがそれほど多くありません(たとえば、 this とは対照的です)。 編集:この場合は注目に値しますが tschaibleのScannerソリューション これ以上コードはありません!
欠点:あなたは明らかにこのためだけに新しいライブラリの依存関係を追加したくないかもしれません。 (それから、あなたのプロジェクトでGuavaを利用しないのは愚かなことです。;-)
このような単純で一般的なものについては、 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(" "));
完了しました。
Java 7を使用して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行ずつ読み取り、その行をString
として受け取り、次にString
を処理することです。
これが理解するのが最も簡単な方法であることは疑いようがありません、そしてファイルがかなり短い(例えば、何万行も)場合、それは効率の点でも許容できるでしょう。 しかし、ファイルが長い場合、それを行うには非常に非効率的な方法です。2つの理由があります。
String
の作成時、もう1回は処理時です。String
を作成し、次の行に移動したらそれを捨てます。ガベージコレクタは、最終的には不要になったこれらすべてのString
オブジェクトを破棄する必要があります。誰かがあなたの後を片付けなければなりません。速度を気にしているのであれば、データブロックを読み込んでから1行ずつではなく、1バイトずつ処理したほうがはるかに良いでしょう。あなたが数の終わりに達するたびに、あなたはあなたが構築している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
ベースのアプローチのどれよりも、はるかに速く速くなります。非常によく似た問題についての詳細な調査があります この質問では 。マルチスレッド化したい場合は、さらに改善する可能性があります。
ファイルを読み、Java8 Files.lines(Paths.get( "c://lines.txt"))。collect(Collectors.toList());を実行します。