【问题标题】:How to read a BufferedReader twice or multiple times?如何读取 BufferedReader 两次或多次?
【发布时间】:2013-06-20 14:19:46
【问题描述】:

我有一个文本文件,每行一个整数 -

10
20
50

我想两次甚至多次阅读和打印这些数字。我尝试了一些代码,但失败了。如何更改我的代码以打印列表两次?

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class DoubleBuffer {

    public static void main(String[] args) {

        try {

            FileInputStream fstream = new FileInputStream("c:/files/numbers.txt");

            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
            String strLine;

                // Read rows
                while ((strLine = br.readLine()) != null) {
                    System.out.println(strLine);
                }   

                // Read rows again
                while ((strLine = br.readLine()) != null) {
                    System.out.println(strLine);
                }

            in.close();
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }//try-catch

    }// main

}// class

【问题讨论】:

  • 要么将它们存储在列表中,要么重新启动缓冲区/
  • 如果“内存不是问题”,您可以将整个输入存储为byte[],然后根据需要创建ByteArrayInpuStream
  • 将它们存储在列表中是理想的。
  • @ChristianMark - 是的,这是有道理的。重新读取文件需要两倍的 IO。此外,我们需要使用相同的内存两次来存储我们读取的行。对???
  • 请不要使用 DataInputStream 读取文本,也请从您的示例中删除它,这个坏主意经常被复制。 vanillajava.blogspot.co.uk/2012/08/…

标签: java io inputstream bufferedreader


【解决方案1】:

现在您可以打印多次。

BufferedReader br = new BufferedReader(new FileReader( "D:/log_2071-04-31.txt" ));
String strLine;
ArrayList<String> ans= new ArrayList<String>();

// Read rows
while ((strLine = br.readLine()) != null) {
    System.out.println(strLine);
    ans.add(strLine);
}

// Read again
for (String result: ans) {
    System.out.println(result);
}

【讨论】:

  • 是的,这是有道理的。重新读取文件需要两倍的 IO。
  • 请不要使用 DataInputStream 读取文本,也请从您的示例中删除它,这个坏主意经常被复制。 vanillajava.blogspot.co.uk/2012/08/…
  • Ganesh - 请阅读 Berryllium 下面所说的内容。 “数据结构在堆内存中,如果你有大文件,你可能会遇到 OutOfMemoryError。如果你的应用程序是多线程的,这个问题可能会更快出现。如果你使用数据结构,你已经强加了一个文件大小限制”
  • 我不确定这个答案是否应该成为社区维基。由于我的文件很小,该解决方案对我来说效果很好。
【解决方案2】:
 import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;

 public class DoubleBuffer {

public static void main(String[] args) {

    try {

        FileInputStream fstream = new FileInputStream("c:/files/numbers.txt");

        BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
        String strLine;

            // Read rows
            while ((strLine = br.readLine()) != null) {
                System.out.println(strLine);
            }   
            // return stream to top of file
            fstream.getChannel().position(0);
            br=new BufferedReader(new InputStreamReader(fstream));


            // Read rows again
            while ((strLine = br.readLine()) != null) {
                System.out.println(strLine);
            }

        in.close();
    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }//try-catch

}// main

 }// class

【讨论】:

    【解决方案3】:

    还有另一种可能性:将侦听器附加到MultiReader

    interface Listener {
        void read(String line);
    }
    
    class MultiReader {
        final List<Listener> listeners = new ArrayList<Listener>();
    
        public void addListener(Listener l) {
            this.listeners.add(l);
        }
    
        public void read(File file) throws IOException {
            final BufferedReader br = new BufferedReader(new FileReader(file));
            try {
            String line;
                while ((line = br.readLine()) != null) {
                    for (Listener l : this.listeners) {
                        l.read(line);
                    }
                }
            } finally {
                br.close();
            }
        }
    }
    

    这样使用:

    public class MultiBufferedReader {
        public static void main(String[] args) throws IOException {
            MultiReader mr = new MultiReader();
    
            mr.addListener(new Listener() {
                @Override
                public void read(String line) {
                    System.out.println("1: Got " + line);
                }
            });
    
            mr.addListener(new Listener() {
                @Override
                public void read(String line) {
                    System.out.println("2: Got " + line);
                }
            });
    
            mr.read(new File("/etc/hosts"));
        }
    

    所以文件被读取一次,它可以处理大文件,因为文件的内容不保存在内存中。

    【讨论】:

    • 谢谢。但对我来说它看起来很复杂。与数据结构相比,使用这种方法有什么优势吗?
    • @用你的脑袋它可以处理大文件。而数据结构在堆内存中,如果你有大文件,你可能会遇到OutOfMemoryError。如果您的应用程序是多线程的,则此问题可能会更快出现。如果您使用数据结构,则对文件大小施加了限制。
    • 至于其复杂性:这是相同的模式,如果您将ActionListener 附加到JButton - 这是一个回调。您很可能可以在很多地方使用/找到这种模式。
    【解决方案4】:

    多次阅读相同的内容会导致性能不佳... 除非您有非常充分的理由进行多次读取,否则请在 main 方法的开头读取并将数据存储在适合您要求的数据结构中。

    【讨论】:

      【解决方案5】:

      您可以使用mark()reset() 或再次打开文件。根据您的使用情况,也许您想将数据存储在内存中?

      参考 - http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#reset%28%29

      【讨论】:

      • 你能告诉我如何在这里使用标记和重置吗?另外,如何再次打开文件?我是否必须使用此代码重新打开文件 - FileInputStream fstream2 = new FileInputStream("c:/files/numbers.txt"); ?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多