[英]RandomAccessFile and read/write start-finish position
I've searched this a lot but still can't find... So I hope you can help me to understand :) 我已经搜索了很多,但仍然找不到...所以希望您能帮助我理解:)
The question is... 问题是...
I have big file A.dat and I want 我有大文件A.dat,我想要
But I have a problem... If I have a file which length cannot be devided by 4Mb the data get lost and file become corrupted :( 但是我有一个问题...如果我有一个文件长度不能由4Mb划分,则数据会丢失并且文件会损坏:(
For example... I have media file. 例如...我有媒体文件。 Its length is 15.8Mb so I can get only 15.8Mb/4Mb=3 whole pieces.
它的长度是15.8Mb,所以我只能得到15.8Mb / 4Mb = 3整块。 Then I can write only those 3 bytes pieces and the rest get lost :( Or the problem is if file is smaller than buffer size (4Mb)...
然后我只能写那3个字节的片段,其余的会丢失:(或问题是如果文件小于缓冲区大小(4Mb)...
I think it shouldn't be a hard task but I couldn't see any standart tutorial which shows how to solve such kind of things... 我认为这不应该是一项艰巨的任务,但我看不到任何标准的教程来展示如何解决这类问题...
I dearly hope you can help me with this question. 我非常希望您能在这个问题上帮助我。
A RandomAccessFile
does not seem useful in this case. 在这种情况下,
RandomAccessFile
似乎没有用。 Using traditional stream-based I/O is best and certainly won't lead to out of memory errors unless you're doing it wrong. 最好使用传统的基于流的I / O,除非您做错了,否则肯定不会导致内存不足错误。 Here's really all the code you need (untested):
这实际上是您需要的所有代码(未经测试):
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream("a.dat");
out = new FileInputStream("b.dat");
byte[] buffer = new byte[4*1024*1042]; //4 MiB
for ( int len = 0; (len = in.read(buffer)) != -1; ) {
out.write(buffer, 0, len);
}
} finally {
if ( in != null )
try { in.close() } catch (IOException ignore) {}
if ( out != null )
try { out.close() } catch (IOException ignore) {}
}
If you really need a RandomAccessFile
for some reason you can't tell us, the method is essentially the same. 如果由于某种原因您确实需要一个
RandomAccessFile
,但您不能告诉我们,则方法本质上是相同的。 Find out how much data you actually read into your buffer using the result from RandomAccessFile.read(byte[], int, int)
and use that number to limit how much you write back to the output file. 使用
RandomAccessFile.read(byte[], int, int)
的结果,找出实际读入缓冲区的数据量RandomAccessFile.read(byte[], int, int)
并使用该数字来限制写回输出文件的量。
The above warrants some explanation. 上面有一些解释。 Here are the key parts:
以下是关键部分:
byte[] buffer = new byte[4*1024*1042]; //4 MiB
This initializes a byte array of 4 binary megabytes which will hold one chunk of the file at a time. 这将初始化一个4二进制兆字节的字节数组,该字节数组一次将保存一个文件块。
for ( int len = 0;
In a for loop, we start by declaring a value len
that will record how many bytes we have read in. 在for循环中,我们首先声明一个值
len
,该值将记录我们已读入的字节数。
(len = in.read(buffer)) != -1;
Then we invoke read
on the InputStream
. 然后,我们在
InputStream
上调用read
。 This will read bytes into the byte array until either the buffer is full, or there is no more data left to read (the end of file is reached). 这会将字节读取到字节数组中,直到缓冲区已满或没有更多数据可读取(到达文件末尾)为止。 The number of bytes actually read is returned by this method and assigned to
len
. 该方法返回实际读取的字节数,并将其分配给
len
。 If that value is -1, that means the stream is closed so we exit the loop. 如果该值为-1,则表示流已关闭,因此我们退出循环。
) {
out.write(buffer, 0, len);
}
Then, for each chunk that we have read, we write it to the output stream. 然后,对于已读取的每个块,将其写入输出流。
buffer
indicates we want to write from our byte array, the 0
indicates we want to start at the beginning of the array, and the len
says how many bytes to write. buffer
表示我们要从字节数组中写入, 0
表示我们要从数组的开头开始, len
表示要写入多少字节。 Remember, if our buffer wasn't filled then len
will have been set accordingly and only part of the array will be written. 请记住,如果未填充缓冲区,则将相应地设置
len
,并且仅写入数组的一部分。
I gave you the idiomatic version which can be more difficult to follow. 我给了你惯用的版本,可能很难理解。 Here's a more straightforward way of doing the same thing:
这是做同一件事的更直接的方法:
int numberOfBytesRead;
while ( true ) {
numberOfBytesRead = in.read(buffer); //read bytes into buffer
if ( numberOfBytesRead == -1 ) break; //end of stream
out.write(buffer, 0, numberOfBytesRead); //write the same # of bytes we read
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.