50+ GB分隔文件中的近似行数

时间:2015-06-03 12:13:06

标签: java

我需要通过检查文件中的行数是否匹配(近似)附加到预告片的数字来验证相当大的分隔文件。

方法很少,我不接受:

- 在堆中放入整个文件

- 在验证步骤完成之前,处理无法启动。

到目前为止我所拥有的:

我拖尾并解析预告片以获得行数,这非常有效。

我打算做什么: 从文件中获取0.5 / 1mb的行样本(理想情况下是随机的),计算其中的行并相应地相乘,以获得整个文件中行的近似值。

我不想限制自己通过读取第一行“n”行来创建样本,然后检查其大小......

问题:

是否有可能获得这样的样本,而无需读取整个文件?我是否可以从文件中间开始获取n行,而无需重新创建原始文件的一部分(例如head '-c/n' 'x' file.csv > file1.csv效率不高)?

2 个答案:

答案 0 :(得分:1)

  

是否有可能获得这样的样本,而无需读取整个文件?

  

我可以从文件中间开始提取n行,而无需重新创建原始文件的一部分。

  • 使用File.length()获取文件的长度。
  • 使用FileInputStream
  • 打开文件
  • 使用FileInputStream.skip(N)跳到要采样的偏移量。 (我已检查过Java 8源代码,skip效率很高。它使用lseek系统调用而不是读取字节...)
  • 最后,将流包裹在BufferedReader(InputStreamReader)中并使用BufferedReader.readLine()计算M行并计算其平均长度。

稍微退一步,我对问题本身有几点意见:

  

我需要通过检查文件中的行数是否匹配(近似)附加到预告片的数字来验证相当大的分隔文件。

  1. 目前尚不清楚近似匹配是否有多大帮助。我想,这取决于你试图检测的失败模式。

  2. 您不希望大多数/所有输入文件的平均记录相同吗?如果是这样,将行数(来自预告片)与文件大小x预期的平均记录数进行验证可能更有意义。

  3. 在一小部分记录不好的情况下,采样不会发现问题。而且这种不良可能是空行或多个/大多数/所有字段为空的记录。

  4. 还有一个问题是,做一个单独的"快速"是否是一个好主意。验证一个这么大的文件。如果您发现问题,您可以做什么?重新获取它?重新发送?在处理它时,进行完整验证是不是更好?将文件缩小会不会更好?对于这样大小的文件,选择比CSV更紧凑的表示形式会不会更好?

答案 1 :(得分:0)

如果您的文件大小为50 GB,那么将整个文件放入堆中确实可能不太好。

您可以使用内存映射文件,例如,您可以读取整个文件,而无需将其完全加载到主内存中。

您可以使用RandomAccessFile和MappedByteBuffer打开 文件的一个区域作为MemoryMapped缓冲区。 看看RandomAccessFile.getChannel和FileChannel.map方法。