簡體   English   中英

Java:如何讀取文本文件

[英]Java: How to read a text file

我想讀取包含空格分隔值的文本文件。 值是整數。 如何閱讀並將其放入數組列表?

以下是文本文件內容的示例:

1 62 4 55 5 6 77

我想把它放在一個arraylist中[1, 62, 4, 55, 5, 6, 77] 1,62,4,55,5,6,77 [1, 62, 4, 55, 5, 6, 77] 我怎么能用Java做呢?

您可以使用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()String轉換為Integer

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,那么您甚至可以使用Stream API ,從Files#lines()

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 Collections )。

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的掃描儀解決方案沒有更多的代碼!

缺點:你顯然可能不想為此添加新的庫依賴項。 (再說一次,你在項目中不要使用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);

到目前為止,所有答案都涉及逐行讀取文件,將行作為String ,然后處理String

毫無疑問,這是最容易理解的方法,如果文件相當短(比如成千上萬行),那么在效率方面也是可以接受的。 但是如果文件很長 ,那么這是一種非常低效的方法,原因有兩個:

  1. 每個字符都被處理兩次,一次在構造String ,一次處理它。
  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為基礎的方法都要快得多 ,這也是這個問題的答案。 在這個問題中有一個非常類似問題的詳細調查。 如果你想沿着多線程線走下去,你會發現還有可能進一步改進它。

讀取文件,然后執行任何你想要的java8 Files.lines(Paths.get(“c://lines.txt”))。collect(Collectors.toList());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM