Java:如何读取文本文件

发布于 2024-08-31 15:37:03 字数 190 浏览 1 评论 0原文

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

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

1 62 4 55 5 6 77

我希望将其作为 [1, 62, 4, 55, 5, 6, 77] 放入数组列表中。我怎样才能用Java做到这一点?

I want to read a text file containing space separated values. Values are integers.
How can I read it and put it in an array list?

Here is an example of contents of the text file:

1 62 4 55 5 6 77

I want to have it in an arraylist as [1, 62, 4, 55, 5, 6, 77]. How can I do it in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

南街女流氓 2024-09-07 15:37:04

到目前为止给出的所有答案都涉及逐行读取文件,将该行作为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 的方法(也作为该问题的答案给出)快得多在此问题中。您会看到,如果您想继续使用多线程,则可以进一步改进它。

All the answers so far given involve reading the file line by line, taking the line in as a String, and then processing the String.

There is no question that this is the easiest approach to understand, and if the file is fairly short (say, tens of thousands of lines), it'll also be acceptable in terms of efficiency. But if the file is long, it's a very inefficient way to do it, for two reasons:

  1. Every character gets processed twice, once in constructing the String, and once in processing it.
  2. The garbage collector will not be your friend if there are lots of lines in the file. You're constructing a new String for each line, and then throwing it away when you move to the next line. The garbage collector will eventually have to dispose of all these String objects that you don't want any more. Someone's got to clean up after you.

If you care about speed, you are much better off reading a block of data and then processing it byte by byte rather than line by line. Every time you come to the end of a number, you add it to the List you're building.

It will come out something like this:

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;
}

The code above assumes that this is ASCII (though it could be easily tweaked for other encodings), and that anything that isn't a digit (in particular, a space or a newline) represents a boundary between digits. It also assumes that the file ends with a non-digit (in practice, that the last line ends with a newline), though, again, it could be tweaked to deal with the case where it doesn't.

It's much, much faster than any of the String-based approaches also given as answers to this question. There is a detailed investigation of a very similar issue in this question. You'll see there that there's the possibility of improving it still further if you want to go down the multi-threaded line.

变身佩奇 2024-09-07 15:37:04

读取文件,然后做你想做的事
java8
Files.lines(Paths.get("c://lines.txt")).collect(Collectors.toList());

read the file and then do whatever you want
java8
Files.lines(Paths.get("c://lines.txt")).collect(Collectors.toList());

浅忆流年 2024-09-07 15:37:03

您可以使用 Files#readAllLines() 将文本文件的所有行获取到 List 中。

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 流处理数据

You can use Files#readAllLines() to get all lines of a text file into a List<String>.

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

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


You can use String#split() to split a String in parts based on a regular expression.

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

Tutorial: Numbers and Strings > Strings > Manipulating Characters in a String


You can use Integer#valueOf() to convert a String into an Integer.

Integer i = Integer.valueOf(part);

Tutorial: Numbers and Strings > Strings > Converting between Numbers and Strings


You can use List#add() to add an element to a List.

numbers.add(i);

Tutorial: Interfaces > The List Interface


So, in a nutshell (assuming that the file doesn't have empty lines nor trailing/leading whitespace).

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

If you happen to be at Java 8 already, then you can even use Stream API for this, starting with 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());

Tutorial: Processing data with Java 8 streams

巷子口的你 2024-09-07 15:37:03

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 1.5 introduced the Scanner class for handling input from file and streams.

It is used for getting integers from a file and would look something like this:

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

Check the API though. There are many more options for dealing with different types of input sources, differing delimiters, and differing data types.

时光瘦了 2024-09-07 15:37:03

此示例代码向您展示了如何用 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());                      
       }

     }
  }

This example code shows you how to read file in 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());                      
       }

     }
  }
秋千易 2024-09-07 15:37:03

看一下这个例子,并尝试做你自己的:

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

Look at this example, and try to do your own:

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());
        }
    }
}
牛↙奶布丁 2024-09-07 15:37:03

只是为了好玩,这就是我在实际项目中可能会做的事情,其中​​我已经使用了所有我最喜欢的库(在本例中 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,那你就太傻了。;-)

Just for fun, here's what I'd probably do in a real project, where I'm already using all my favourite libraries (in this case Guava, formerly known as 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));
}

Benefit: Not much own code to maintain (contrast with e.g. this). Edit: Although it is worth noting that in this case tschaible's Scanner solution doesn't have any more code!

Drawback: you obviously may not want to add new library dependencies just for this. (Then again, you'd be silly not to make use of Guava in your projects. ;-)

不气馁 2024-09-07 15:37:03

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

完成。

Use Apache Commons (IO and Lang) for simple/common things like this.

Imports:

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

Code:

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

Done.

乄_柒ぐ汐 2024-09-07 15:37:03

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

Using Java 7 to read files with NIO.2

Import these packages:

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

This is the process to read a file:

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

To read all lines of a file at once:

Path file = Paths.get("C:\\Java\\file.txt");
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文