Java:如何读取文本文件

时间:2010-05-07 11:17:32

标签: java arraylist file-io text-files

我想读取包含空格分隔值的文本文件。值是整数。 如何阅读并将其放入数组列表?

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

1 62 4 55 5 6 77

我想把它作为[1, 62, 4, 55, 5, 6, 77]放在arraylist中。我怎么能用Java做到这一点?

9 个答案:

答案 0 :(得分:170)

您可以使用Files#readAllLines()将文本文件的所有行都放入List<String>

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

教程:Basic I/O > File I/O > Reading, Writing and Creating text files


您可以使用String#split()根据正则表达式分割String部分内容。

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

教程:Numbers and Strings > Strings > Manipulating Characters in a String


您可以使用Integer#valueOf()String转换为Integer

Integer i = Integer.valueOf(part);

教程:Numbers and Strings > Strings > Converting between Numbers and Strings


您可以使用List#add()List添加元素。

numbers.add(i);

教程:Interfaces > The List Interface


因此,简而言之(假设文件没有空行也没有尾随/前导空格)。

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());

教程:Processing data with Java 8 streams

答案 1 :(得分: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 :(得分: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());                      
       }

     }
  }

答案 3 :(得分: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());
        }
    }
}

答案 4 :(得分:5)

只是为了好玩,这是我在真实项目中可能会做的事情,我已经在使用我最喜欢的所有库(在这种情况下为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));
}

好处:维护自己的代码不多(与例如this形成对比)。 编辑:虽然值得注意的是,在这种情况下tschaible's Scanner solution没有更多代码!

缺点:你显然可能不想为此添加新的库依赖项。 (再说一遍,你在项目中不要使用Guava是愚蠢的。; - )

答案 5 :(得分: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(" "));

完成。

答案 6 :(得分:2)

使用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);

答案 7 :(得分:1)

到目前为止,所有答案都涉及逐行阅读文件,将该行作为String,然后处理String

毫无疑问,这是最容易理解的方法,如果文件相当短(例如,成千上万行),它在效率方面也是可以接受的。 但如果文件很长,这是一种非常低效的方法,原因有两个:

  1. 每个角色都会被处理两次,一次是在构建String时,一次是在处理它时。
  2. 如果文件中有很多行,垃圾收集器将不是您的朋友。您为每一行构建了一个新的String,然后在移动到下一行时将其丢弃。垃圾收集器最终将不得不处理您不再需要的所有String个对象。有人要跟你清理。
  3. 如果您关心速度,那么阅读数据块然后逐字节而不是逐行处理它会好得多。每当您到达某个数字的末尾时,都会将其添加到您正在构建的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的方法更快,更快也作为这个问题的答案。对一个非常类似的问题in this question进行了详细调查。如果你想沿着多线程线走下去,那么你可以看到那里还有进一步改进它的可能性。

答案 8 :(得分:0)

阅读文件然后做你想做的事 java8 Files.lines(Paths.get( “C://lines.txt”))。收集(Collectors.toList());