[英]Java: Writing with FileChannel to a file make the file shrink?
I tried to write specific bytes to certain position of a file using FileChannel. 我试图使用FileChannel将特定字节写入文件的特定位置。 But actually the file shrink to the last position where I write change.
但是实际上文件缩小到了我写更改的最后位置。 I do it like this:
我这样做是这样的:
Path path = Paths.get("I://music - Copy.mp3");
System.out.println(Files.size(path)/1024 + "KB");
try (FileChannel chan = new FileOutputStream(path.toFile()).getChannel()) {
chan.position(1024 * 1024);
ByteBuffer b = ByteBuffer.allocate(1024);
chan.write(b);
System.out.println("Write 1KB of data");
}
System.out.println(Files.size(path)/1024 + "KB");
and this is the output I get: 这是我得到的输出:
3670KB
Write 1KB of data
1025KB
Can anybody tell me where it goes wrong?? 谁能告诉我哪里出了问题?
You're missing the FileOutputStream constructor which allows to append to the file. 您缺少允许附加到文件的FileOutputStream构造函数 。 If you create it as above, you overwrite the content of the file.
如果按上述方式创建,则会覆盖文件的内容。
try to use your FileOutputStream
in append mode and avoid specifing current channel position: 尝试在附加模式下使用
FileOutputStream
并避免指定当前通道位置:
new FileOutputStream(path.toFile(), true)
upd. UPD。 didn't see the prevoius answer
没有看到prevoius的答案
FileOutputStream truncates the file to zero length when not in append mode. 如果不在附加模式下,FileOutputStream会将文件截断为零长度。 It does not overwrite a file's contents so much as it throws away the contents and starts over.
它不会覆盖文件的内容,而是会丢弃内容并重新开始。 You can verify this by calling
chan.size()
after creating the channel, which will give you 0. [1] 您可以在创建通道后通过调用
chan.size()
进行验证,这将为您提供0。 [1]
FileChannels can be advanced past the end of a file and told to write there; 可以将FileChannels推进到文件末尾并告知在其中写入; this causes the file size to increase to position + bytes_written (emphasis mine):
这导致文件大小增加到position + bytes_write(重点是我的):
Setting the position to a value that is greater than the current size is legal but does not change the size of the entity.
将头寸设置为大于当前大小的值是合法的,但不会更改实体的大小。 [..] A later attempt to write bytes at such a position will cause the entity to grow to accommodate the new bytes ;
[..] 以后尝试在此位置写入字节将导致实体增长以容纳新的字节 ; the values of any bytes between the previous end-of-file and the newly-written bytes are unspecified.
未指定前一个文件末尾与新写入的字节之间的任何字节的值。
So while it looks like the FileChannel is cutting off your file after writing, it is the FileOutputStream truncating to 0 length, and then the FileChannel expanding it again. 因此,尽管看起来FileChannel在写入后正在切断文件,但FileOutputStream会截断为0的长度,然后FileChannel再次将其扩展。
To prevent this from happening, avoid using a FileOutputStream to create a channel. 为防止这种情况发生,请避免使用FileOutputStream创建通道。 You have a Path, so you can call
Files.newByteChannel
or FileChannel.open
: 您具有路径,因此可以调用
Files.newByteChannel
或FileChannel.open
:
Path path = Paths.get("I://music - Copy.mp3");
System.out.println(Files.size(path)/1024 + "KB");
// pick either:
try (FileChannel chan = FileChannel.open(path, StandardOpenOption.WRITE)) {
try (SeekableByteChannel chan = Files.newByteChannel(path, StandardOpenOption.WRITE)) {
chan.position(1024 * 1024);
ByteBuffer b = ByteBuffer.allocate(1024);
chan.write(b);
System.out.println("Write 1KB of data");
}
System.out.println(Files.size(path)/1024 + "KB");
[1] Note that programs outside the JVM, such as a file explorer, may not indicate this until you flush or close the stream. [1]请注意,除非刷新或关闭流,否则JVM外部的程序(例如文件浏览器)可能不会表明这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.