的问题是,以容纳所有这些数据所需要的阵列比MAX_BUFFER_SIZE
更大,这是在定义java.nio.Files
为Integer.MAX_VALUE - 8
:
public static byte[] readAllBytes(Path path) throws IOException {
try (SeekableByteChannel sbc = Files.newByteChannel(path);
InputStream in = Channels.newInputStream(sbc)) {
long size = sbc.size();
if (size > (long)MAX_BUFFER_SIZE)
throw new OutOfMemoryError("Required array size too large");
return read(in, (int)size);
}
}
这是必要的,因为数组通过整数进行索引 - 这是您可以获得的最大数组。
你有三个选择:
流通过文件
也就是说,打开文件,读取块,处理它,阅读另一块,对它进行处理,一次又一次,直到你”已经经历了整个事情。
Java提供了很多类来执行此操作:InputStream
,Reader
,Scanner
等 - 它们在大多数Java入门课程和书籍中都有讨论。研究其中之一。
例https://stackoverflow.com/a/21706141/7512
这样做的有效性取决于你能够做一些有意义的事情与文件的早期部分,不知道将会发生什么。很多时候都是这样。其他时候,您必须在文件中进行多次传递。
文件格式通常被设计为可以一次完成处理 - 根据这个设计自己的文件格式是一个不错的主意。
我注意到你的文件是一个.trec
文件,它是一个屏幕捕获的视频。视频和音频格式很可能是为流媒体而设计的 - 这是您可以在下载结束之前观看YouTube视频的开始的原因。
内存映射
如果你真的需要跳来跳去的文件来处理它的内容,你可以作为一个内存映射文件打开它。
查看RandomAccessFile
的文档 - 这为您提供了一个seek()
方法的对象,因此您可以读取文件数据中的任意点。
阅读到多个阵列
我包括这仅出于完整性;将整个文件整理成堆内存很难。但如果你真的想,你可以将这些字节存储在一些数组中 - 也许是List<byte[]>
。 Java-ish伪代码:
List<byte[]> filecontents = new ArrayList<byte[]>();
InputStream is = new FileInputStream(...);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
int bytesGot = readUpToMaxBufferSizeFrom(file);
while(bytesGot != -1) {
byte[] chunk = new byte[bytesGot];
System.arrayCopy(buffer, 0, chunk, 0, bytesGot);
filecontents.add(chunk);
}
这允许你达到MAX_BUFFER_SIZE * Integer.MAX_INTEGER
字节。访问内容比使用简单的数组稍微复杂一点 - 但是实现细节可以隐藏在类中。
你会的,当然,需要配置的Java有一个巨大的堆大小 - 见How to set the maximum memory usage for JVM?
不要这样做。
内容是一个有限的大小的数组,你是溢出.... –
我知道,但我应该如何阅读内容呢? – Niton
你会流它。读取一些数据,做你需要的东西,读下一个位等 – pandaadb