Java:使用FileChannel写入文件会使文件收缩吗?
我尝试使用FileChannel将特定字节写入文件的特定位置。但实际上,文件收缩到我写更改的最后一个位置。我是这样做的:Java:使用FileChannel写入文件会使文件收缩吗?,java,file-io,filechannel,Java,File Io,Filechannel,我尝试使用FileChannel将特定字节写入文件的特定位置。但实际上,文件收缩到我写更改的最后一个位置。我是这样做的: Path path = Paths.get("I://music - Copy.mp3"); System.out.println(Files.size(path)/1024 + "KB"); try (FileChannel chan = new FileOutputStream(path.toFile()).getChannel()) {
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");
这是我得到的输出:
3670KB
Write 1KB of data
1025KB
有人能告诉我哪里出错了吗???您缺少允许附加到文件的。如果按上述方式创建,则会覆盖文件内容。请尝试在追加模式下使用
FileOutputStream
,并避免指定当前频道位置:
new FileOutputStream(path.toFile(), true)
upd。未看到上一个答案FileOutputStream在未处于追加模式时将文件截断为零长度。它不会覆盖文件的内容,而是会丢弃内容并重新开始。您可以在创建频道后调用
chan.size()
来验证这一点,这将为您提供0。[1]
FileChannels可以前进到文件末尾,并被告知在那里写入;这会导致文件大小增加到位置+写入字节数(强调):
将位置设置为大于当前大小的值是合法的,但不会更改实体的大小。[……]稍后在该位置写入字节的尝试将导致实体增长以容纳新字节;未指定文件前一个结尾和新写入的字节之间的任何字节的值
因此,虽然看起来FileChannel在写入后会切断您的文件,但是FileOutputStream会截断为0长度,然后FileChannel会再次扩展它
要防止这种情况发生,请避免使用FileOutputStream创建通道。您有路径,因此可以调用或:
[1] 请注意,JVM之外的程序,如文件浏览器,在刷新或关闭流之前可能不会显示此信息。频道定位不是问题-我认为您应该编辑它。我尝试了一下,结果输出大小增加了1 KB(3670KB-3671KB)。这难道不意味着它被写到文件的末尾,而不是指定的位置吗?
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");