首页 > 解决方案 > 如何防止 MappedByteBuffer 在文件末尾写入空字符?

问题描述

作为分配的一部分,我正在使用具有固定缓冲区大小的 Java 的 MappedByteBuffer 写入文件。它应该逐个字符地写入,因为缓冲区大小可以小于行长。但问题是它将文件末尾缓冲区的剩余位置写为空字符。如何删除那些空字符?

这是一个示例代码:

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class Main {
    public static void main(String[] args) throws IOException {
        int bufferSize = 20;
        RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
        MappedByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, bufferSize);

        for (char c : "Line1".toCharArray()) {
            buffer.put((byte) c);
        }
        buffer.put((byte)'\n');
        for (char c : "Line2".toCharArray()) {
            buffer.put((byte) c);
        }
    }
}

这是输出(使用 Sublime Text utf-8 编码打开):

标签: javamappedbytebuffer

解决方案


正如 Progman 所指出的,截断将解决您所看到的问题。我使用 TextWrangler 复制了您看到的内容并显示了隐藏字符,然后我使用以下代码重新编写了它,并且尾随的空值消失了。关键的变化是跟踪实际写入的字节数,然后将文件截断为该长度。

int bufferSize = 20;
int bytesWritten = 0;
RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
MappedByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, bufferSize);

for (char c: "Line1".toCharArray()) {
    buffer.put((byte) c);
    bytesWritten++;
}
buffer.put((byte)
    '\n');
bytesWritten++;
for (char c: "Line2".toCharArray()) {
    buffer.put((byte) c);
    bytesWritten++;
}
buffer.force(); //make sure all is written before messing with truncating
file.getChannel().truncate(bytesWritten);

推荐阅读