【发布时间】:2016-08-22 09:50:47
【问题描述】:
我正在做一些不寻常的数据操作。我有 36,000 个输入文件。更多则可以一次加载到内存中。我想获取每个文件的第一个字节并将其放入一个输出文件中,然后对第二个文件再次执行此操作,依此类推。它不需要以任何特定的顺序完成。因为输入文件是压缩的,加载它们需要更长的时间,并且一次不能读取 1 个字节。我最终得到每个输入文件的字节数组。
输入文件大约为 ~1-6MB 未压缩和 ~.3-1MB 压缩(有损压缩)。输出文件最终是输入文件的字节数。在我的示例中约为 36KB。
我知道 ulimit 可以在 Linux 操作系统上设置,等效的可以在 Windows 上完成。即使这个数字可以提高,我认为任何操作系统都不会喜欢同时写入数百万个文件。
我目前的解决方案是制作 3000 个左右的缓冲写入器流并依次加载每个输入文件并将 1 个字节写入 3000 个文件,然后关闭文件并加载下一个输入。使用这个系统,每个输入文件都需要打开大约 500 次。
整个操作需要 8 天才能完成,并且只是一个更实际的应用程序的测试用例,最终会产生更大的输入文件、更多的文件和更多的输出文件。
在内存中捕获所有压缩文件,然后根据需要解压缩它们听起来不切实际,并且不会扩展到更大的输入文件。
我认为解决方案是从输入文件中缓冲我可以缓冲的内容(因为内存限制不允许缓冲所有内容),然后按顺序写入文件,然后重新执行。
但是我不知道是否有更好的解决方案使用我没有读过的东西。
编辑 我很感谢您的快速反应。我知道我在应用我正在做的事情时含糊其辞,我会努力纠正它。我基本上有一个三维数组 [images][X][Y] 我想遍历每个图像并保存每个图像上特定像素的每种颜色,并对所有图像执行此操作。问题是内存限制。
byte[] 像素 = ((DataBufferByte) ImageIO.read( fileList.get(k) ).getRaster().getDataBuffer()).getData();
这是我用来加载图像的方法,因为它负责解压缩和跳过标题。
我没有将它作为视频进行编辑,因为我必须先获取一帧,然后将其转换为图像(代价高昂的色彩空间转换),然后再将其转换为字节 [] 以获得像素数据 int RGB色彩空间。
我可以加载每个图像并将其拆分为约 500 个部分(Y 大小)并写入我保持打开并为每个图像写入的单独文件。输出很容易在演出下。生成的文件可以完全加载到内存中,并变成一个数组用于顺序文件写入。
中间步骤确实意味着我可以在网络上分担负载,但我试图在具有 4gb 内存、没有 GPU 和低质量 i7 的低质量笔记本电脑上完成它。
在阅读 davidbak 的回复之前,我没有考虑将任何内容保存到文件中作为中间步骤。大小是唯一让这个问题变得不简单的因素,我现在看到大小可以分成更小更易于管理的块。
【问题讨论】:
-
不确定第 3 部分是什么。您需要解压缩文件并将前几个字节附加到文件中吗?为什么要 3,000 个文件?如果你有超过 8 台服务器可以使用 hadoop
-
对于给定的运行,输入的大小都相同,但运行之间的大小可能非常大,文件数量也非常多。如果它是每个 1MB 和 36000 个文件,那么它将是一个 36GB 的文件,这是低端的东西。然后我可以以一种非常可预测的方式读取该文件。我需要的每个字节恰好相隔 1MB(一个输入文件的大小),但请记住将其组装成一个大文件所需的时间,这真的快得多吗?它会将 36 个演出的每个字节加载然后卸载到内存中,以完成 1 个文件。它将执行 100 万次。