BufferedReader:将多行读入单个字符串

22

我正在使用BufferedReader从txt文件中读取数字进行分析。现在的方法是-使用.readline读取一行,使用.split将该字符串拆分为字符串数组。

public InputFile () {
    fileIn = null;

    //stuff here

    fileIn = new FileReader((filename + ".txt"));
    buffIn = new BufferedReader(fileIn);


    return;
    //stuff here
}

public String ReadBigStringIn() {
    String line = null;

    try { line = buffIn.readLine(); }
    catch(IOException e){};

    return line;
}

public ProcessMain() {
    initComponents();
    String[] stringArray;
    String line;

    try {
        InputFile stringIn = new InputFile();
        line = stringIn.ReadBigStringIn();
        stringArray = line.split("[^0-9.+Ee-]+"); 
        // analysis etc.
    }
}

这个方法很好用,但如果txt文件有多行文本怎么办?有没有一种方法可以输出一个单独的长字符串,或者另一种方法来做?也许可以使用while(buffIn.readline != null) {}?不确定如何实现。

欢迎提出想法, 谢谢。

7个回答

35

你说得没错,这里需要一个循环。

通常的惯用法(仅使用纯Java)是这样的:

public String ReadBigStringIn(BufferedReader buffIn) throws IOException {
    StringBuilder everything = new StringBuilder();
    String line;
    while( (line = buffIn.readLine()) != null) {
       everything.append(line);
    }
    return everything.toString();
}

如果您想保留换行符,请勿使用 readLine() 方法,而是直接读入到 char[] 中(并将其附加到 StringBuilder)。

请注意,此循环将一直运行直到流结束(如果没有结束将被阻塞),因此如果需要不同的条件来完成循环,请在其中实现它。


这件事的不好之处在于,由于服务器无休止地等待readLine(),因此您无法在服务器上使用它。 - Niton
@Niton 服务器如何无限等待?如果readLine尝试从没有结束的打开流中读取数据,它将无限等待,但这不仅限于服务器。 - Paŭlo Ebermann
是的,但服务器流(套接字流)只有在关闭时才会结束,因此在服务器上最好使用“消息结束条件”。 (例如,在HTTP请求末尾的空白行中保持流打开,但告诉客户端请求已完成) - Niton
你的答案是正确的,但对于服务器/协议来说可惜不能使用。 不过没关系,我有解决方案,只是想指出一下。 - Niton

6

我强烈建议在这里使用库,但自Java 8以来,您也可以使用流来实现。

    try (InputStreamReader in = new InputStreamReader(System.in);
         BufferedReader buffer = new BufferedReader(in)) {
        final String fileAsText = buffer.lines().collect(Collectors.joining());
        System.out.println(fileAsText);
    } catch (Exception e) {
        e.printStackTrace();
    }

您还可以注意到,它非常有效,因为joining在内部使用了StringBuilder


这是一个很棒的一行代码,不需要迭代缓冲区、检查 null、转换为字符串等。 - membersound
2
如果您想保留行尾,可以将System.lineSeparator()添加为Collectors.joining的参数:buffer.lines().collect(Collectors.joining(System.lineSeparator())) - Aldo Canepa

2
如果您只想将整个文件读入字符串中,我建议您使用Guava的Files类:GuavaFiles类。
String text = Files.toString("filename.txt", Charsets.UTF_8);

当然,这是假设您想保留换行符的情况下。如果您想删除换行符,您可以加载它并使用String.replace,或者再次使用Guava:

List<String> lines = Files.readLines(new File("filename.txt"), Charsets.UTF_8);
String joined = Joiner.on("").join(lines);

1

听起来你想要使用Apache IO FileUtils

String text = FileUtils.readStringFromFile(new File(filename + ".txt"));
String[] stringArray = text.split("[^0-9.+Ee-]+");

0
如果您创建了一个 StringBuilder,那么您可以将每一行附加到它上面,并在结尾处使用 toString() 返回字符串。
您可以用以下代码替换您的 ReadBigStringIn():
public String ReadBigStringIn() {
        StringBuilder b = new StringBuilder();

        try {
            String line = buffIn.readLine();
            while (line != null) {
                b.append(line);
                line = buffIn.readLine();
            }
        }
        catch(IOException e){};

        return b.toString();
}

0

这将创建一个长字符串,每行都用字符串“ ”(一个空格)分隔:

public String ReadBigStringIn() {
    StringBuffer line = new StringBuffer();


    try { 
        while(buffIn.ready()) {
        line.append(" " + buffIn.readLine());
    } catch(IOException e){
        e.printStackTrace();
    }

    return line.toString();
}

0

你有一个包含双精度浮点数的文件。看起来每行可能有多个数字,而且可能有多行。

最简单的方法是在 while 循环中读取每一行。

当到达最后一行时,你可以从 ReadBigStringIn 方法返回 null 并终止循环。

但更正常的做法是在一个方法中创建和使用读取器。也许你可以改为编写一个方法,该方法读取文件并返回双精度浮点数的数组或列表。

顺便说一下,你能否通过空格将字符串分割成数组?

将整个文件读入单个字符串可能适用于你的特定情况,但请注意,如果文件非常大,这可能会导致内存爆炸。对于此类 I/O 操作,流式处理方法通常更安全。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接