写入文件时添加了空格

时间:2018-01-11 09:19:03

标签: java h2 nio bytebuffer filechannel

我正在修改H2 MVStore 1.4.191的源代码,通过做一些线程休眠来写文件。 最大的变化是文件不再在一次写入,而是由2 ^ 16个字节的块组成。 MVStore使用java nio FileChannel和ByteBuffer来编写其文件。问题是结果与原始版本不同。似乎FileChannel添加了空格字符(ASCII中的0x20),比如连续超过40个。或者它可能没有删除这个空格,与原始版本相反,我不知道。

我认为这是由于文件写作。 方法file.write(buffer,position),其中file是FileChannel对象,并返回写入的字节数,有时返回的数字小于缓冲区大小,在原始版本的H2中。在我的版本中,它永远不会发生。

有关于ByteBuffer,FileChannel和我的问题的提示吗?

2 个答案:

答案 0 :(得分:0)

原始代码调用写入函数几次(它写入页眉,页脚和数据)

 int off = 0;
            do {
                int len = file.write(src, pos + off);
                off += len;
            } while (src.remaining() > 0);

src是ByteBuffer,文件是sun.io的FileChannelImpl。缓冲区可以包含超过50MB的数据。

通过这段代码,我开发了一个解决方案,通过在每个缓冲区之间添加睡眠功能,将ByteBuffer分成2 ^ 16大小的缓冲区:

            int off = 0;
            byte[] buffer = src.array();
            int size = src.array().length;
            int chunkSize = 128;
            List<byte[]> splittedBuffer = new ArrayList<byte[]>();
            int i = 0;
            while (i < size) {
                int start = i;
                int end = i + chunkSize;
                if (end > size)
                {
                    //if buffer size is not a multiple of 2^16, the last 
                    //chunk will be smaller 
                    end = size;
                }
                splittedBuffer.add(Arrays.copyOfRange(src.array(), start, end));
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                i += chunkSize;
            }
            int offset = 0;
            for (byte[] chunk : splittedBuffer) {
                int len=file.write(ByteBuffer.wrap(chunk),pos+offset);
                offset+=len;
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

最后,问题可能不是添加了空格,而是一部分数据写在错误的地方。我要检查一下。

答案 1 :(得分:0)

确定,

问题是我使用ByteBuffer的大小来分割它而不是它的更小的限制(在过程中由H2设置)

感谢您的帮助

此致