必须使用skip()或read(),具体取决于应用程序的启动方式

时间:2013-08-31 10:06:08

标签: java inputstream skip

我有一个包含一些数据的文件。每个数据块都有一个索引的起始位置,因此我可以快速访问它。根据程序的启动方式(通过IDE或打开.jar文件),执行input.read()会产生不同的结果。

这是我使用的代码块:

注意:它似乎只发生在那个文件中。

public static void main(String[] args) throws Exception
{
    //The index is at position 137.
    int indexPos = (Character.SIZE / 8) * 137;

    InputStream stream = InputStream stream = Test.class.getResourceAsStream("/data/data.dat");

    int response = JOptionPane.showConfirmDialog(null, "Use skip?");
    if (response == JOptionPane.YES_OPTION)
    {
        //Skips bytes to get to index position.
        stream.skip(indexPos);
    }
    else
    {
        //Reads bytes to get to index position.
        stream.read(new byte[indexPos]);
    }

    byte[] contentStart = new byte[2];
    stream.read(contentStart);

    //The content itself start at this position.
    int contentStartPos = ByteBuffer.wrap(contentStart).order(ByteOrder.BIG_ENDIAN).asCharBuffer().get();

    int response = JOptionPane.showConfirmDialog(null, "Use skip?");

    if (response == JOptionPane.YES_OPTION)
    {
        //Skips bytes to get to the correct position.
        stream.skip(contentStartPos - indexPos - 2);
    }
    else
    {
        //Reads bytes to get to the correct position.
        stream.read(new byte[contentStartPos - indexPos - 2]);
    }

    JOptionPane.showMessageDialog(null, "Should be 0 and is: "+stream.read());
}

以下是最后读取的字节值:

//The correct value needed is 0.
In IDE & yes yes: 108
In IDE & no no: 0
In IDE & yes no: 0
In IDE & no yes: 112
Via JAR & yes yes: 0
Via JAR & no no: 4
Via JAR and yes no: 4
Via JAR and no yes: 0

如您所见,第一次跳过/读取与获取正确值无关紧要。只有第二个。

我希望有人向我解释为什么会这样。

编辑:以下是第二次跳过的值:

//The correct value is 8235.
In IDE using skip: 8190
In IDE using read: 8235
Via JAR using skip: 8235
Via JAR using read: 8192

1 个答案:

答案 0 :(得分:0)

如果有人为InputStream.skip()方法读取Javadoc:

  

从此输入流中跳过并丢弃n个字节的数据。由于各种原因,跳过方法可能最终跳过一些较小数量的字节,可能为0.这可能是由许多条件中的任何一个引起的;在跳过n个字节之前到达文件末尾只有一种可能性。返回跳过的实际字节数。

您需要将跳过放在一个实际上正确跳过字节的循环中。这是人们常犯的错误,我知道过去。正如您所看到的,该方法实际上返回一个long,您可以使用它来跟踪跳过的实际字节数。

我希望这会有所帮助。