奇怪的ByteBuffer输出

时间:2014-05-07 09:35:36

标签: java file outputstream bytebuffer filechannel

当我遇到这个奇怪的问题时,我正在使用ByteBuffers和IntBuffers。这是代码 -

public static void main(String[] args) {
    File file = null;
    FileOutputStream fos = null;
    FileChannel fc = null;
    ByteBuffer bb = ByteBuffer.allocate(1024);
    IntBuffer ib = bb.asIntBuffer();

    ib.put(458215);
    // System.out.println(bb.getInt());  //uncomment this for the program to work flawlessly

    try {
        // Initialize with object references
        file = new File("E:/demjavafiles/text.txt");
        fos = new FileOutputStream(file);
        fc = fos.getChannel();
        System.out.println("Object refrence variables file, fos, fc initialized. Now writing to file....");
        System.out.println("before flip positon : " + bb.position()+ "\n limit: " + bb.limit());
        bb.flip();
        System.out.println("after flip positon : " + bb.position()+ "\n limit: " + bb.limit());

        fc.write(bb);// write buffer
        fc.close();
        System.out.println("buffer written successfully!!");

    } catch (Exception e) {
        System.outprintln("oh oh an error occured D: heres some message 'bout it.");
        e.getMessage();
        e.printStackTrace(System.out);
    } finally {

        System.out.println("End of program....");

    }

}

现在您可以看到的程序创建了ByteBufferIntBuffer并使用put()类的IntBuffer方法添加了int ByteBuffer为4个字节。当我在try块语句之前使用System.out.println(bb.getInt());运行程序时,这是我的输出 -

Object reference variables file, fos, fc initialized. Now writing to file....
before flip position : 0
limit: 1024
after flip posiiton : 0
limit: 0
buffer written successfully!!
End of program....

现在,当我使用System.out.println(bb.getInt());语句再次运行它时,取消注释这是我的输出 -

458215
Object reference variables file, fos, fc initialized. Now writing to file....
before flip position : 4
limit: 1024
after flip position : 0
limit: 4
buffer written successfully!!
End of program....

所以有人可以告诉我为什么会这样吗?

3 个答案:

答案 0 :(得分:1)

bb.getInt()将缓冲区中的位置提前四个字节(所有java.nio缓冲区都有相对puts和gets的内部位置)。使用getInt(someIndex) - 绝对位置变量 - 如果你想保持位置。

答案 1 :(得分:1)

来自JavaDoc

  

public final Buffer flip()

     

翻转此缓冲区。   限制设置为   当前位置然后将位置设置为零。如果标记是   定义然后它被丢弃。

在从缓冲区读取任何内容之前,位置== 0,限制== 0。所以在翻转后,position == 0,limit == 0。

当你getInt()时,位置增加4.所以position == 4,limit == 0.然后flip()执行JavaDoc所说的:position == 0,limit == 4. < / p>

答案 2 :(得分:0)

你在相同的数据上维护两个不同的缓冲区并且它们没有相同的位置,因此当你写入一个时,它不会改变另一个的位置。

我建议您在调试器中单步调试代码,看看发生了什么。

这就是我写它的方式。

public static void main(String... ignored) throws IOException {
    try (FileChannel fc = new FileOutputStream("binary.data").getChannel()) {
        ByteBuffer bb = ByteBuffer.allocate(1024);
        bb.putInt(458215);
        bb.flip();
        fc.write(bb);
        System.out.println("File has " + fc.size() + " bytes in it");
    }
}

打印

File has 4 bytes in it