使用BufferedInputStream读取大文件时截断Java文件IO

时间:2013-05-01 01:31:24

标签: java file file-io bigdata

我有一个函数,我只给了一个BufferedInputStream,没有关于要读取的文件的其他信息。遗憾的是,我无法改变方法定义,因为它是由我无法访问的代码调用的。我一直在使用下面的代码来读取文件并将其内容放在一个字符串中:

public String[] doImport(BufferedInputStream stream) throws IOException, PersistenceException {
    int bytesAvail = stream.available();
    byte[] bytesRead = new byte[bytesAvail];
    stream.read(bytesRead);
    stream.close();
    String fileContents = new String(bytesRead);
    //more code here working with fileContents
}

我的问题是,对于大文件(> 2Gb),此代码会导致程序运行速度极慢或截断数据,具体取决于执行程序的计算机。有没有人建议在这种情况下如何处理大文件?

2 个答案:

答案 0 :(得分:1)

您假设available()返回文件的大小;它不是。它返回可读取的字节数,可以是小于或等于文件大小的任何数字。

不幸的是,如果没有关于文件数据长度的其他信息来源(即通过调用java.io.File.length()),就无法一次性完成所需的操作。相反,您必须从多次读取中累积。一种方法是使用ByteArrayOutputStream。读入固定的有限大小的数组,然后将读取的数据写入ByteArrayOutputStream。最后,拉出字节数组。您需要使用read()write()的三参数形式,并查看read()的返回值,以便确切知道每次调用时读取缓冲区的字节数

答案 1 :(得分:0)

我不确定你为什么不认为你可以逐行阅读。 BufferedInputStream仅描述了如何访问基础流,它不会对您最终如何从中读取数据施加任何限制。您可以像使用任何其他InputStream一样使用它。

即,要逐行阅读

InputStreamReader streamReader = new InputStreamReader(stream);
BufferedInputReader lineReader = new BufferedInputReader(streamReader);
String line = lineReader.readLine();
...

[编辑]这个回答是问题的原始措辞,它专门询问了逐行读取输入文件的方法。