Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Io DataInputStream.skipBytes(n)何时可以不跳过n个字节?_Io_Java - Fatal编程技术网

Io DataInputStream.skipBytes(n)何时可以不跳过n个字节?

Io DataInputStream.skipBytes(n)何时可以不跳过n个字节?,io,java,Io,Java,声明它“试图从输入流中跳过n个字节的数据,丢弃跳过的字节。但是,它可能会跳过一些较小的字节数,可能为零。这可能是由多种情况造成的;在跳过n个字节之前到达文件末尾只是一种可能性。” 除了到达文件末尾,为什么skipBytes()不能跳过正确的字节数?(我正在使用的DataInputStream将包装FileInputStream或PipedInputStream) 如果我确实想跳过n个字节并抛出一个EOFEException,如果这导致我转到文件的末尾,我是否应该使用readFully()并忽略生

声明它“试图从输入流中跳过n个字节的数据,丢弃跳过的字节。但是,它可能会跳过一些较小的字节数,可能为零。这可能是由多种情况造成的;在跳过n个字节之前到达文件末尾只是一种可能性。”

  • 除了到达文件末尾,为什么
    skipBytes()
    不能跳过正确的字节数?(我正在使用的
    DataInputStream
    将包装
    FileInputStream
    PipedInputStream

  • 如果我确实想跳过n个字节并抛出一个
    EOFEException
    ,如果这导致我转到文件的末尾,我是否应该使用
    readFully()
    并忽略生成的字节数组?还是有更好的办法

  • 1) 可能没有那么多数据可供读取(管道的另一端可能还没有发送那么多数据),实现类可能是非阻塞的(即,它只返回它能返回的数据,而不是等待足够的数据来满足请求)

    但是,我不知道是否有任何实现实际上是以这种方式运行的,但是接口的设计允许这样做

    另一个选择是文件在读取过程中部分关闭


    2) readFully()(它将始终等待足够的输入,否则将失败)或在循环中调用skipBytes()。我认为前者可能更好,除非阵列真的很大。

    Josh Bloch最近公布了这一点。这是一致的,因为InputStream.read不能保证读取尽可能多的字节。然而,作为API方法,它是完全没有意义的。InputStream可能也有Readfull。

    事实证明Readfull()增加的性能开销比我愿意忍受的还要多


    最后我妥协了:我调用skipBytes()一次,如果返回的字节数少于正确的字节数,我就为剩余的字节调用readFully()。它读取的是虚拟机上的网络连接,所以我想这可能有很多原因。我通过简单地强制输入流跳过字节数,直到它跳过了我想要的字节数:

    int byteOffsetX = someNumber; //n bytes to skip
    int nSkipped = 0;
    
    nSkipped = in.skipBytes(byteOffsetX);
    while (nSkipped < byteOffsetX) {
        nSkipped = nSkipped + in.skipBytes(byteOffsetX - nSkipped);
    }
    
    int byteOffsetX=someNumber//n个要跳过的字节
    int nSkipped=0;
    nSkipped=in.skipBytes(字节偏移量);
    while(nSkipped
    根据文档,
    readFully()
    是既有效又保证有效的唯一方法

    实际的Oracle实现是。。。令人困惑的:

    public final int skipBytes(int n) throws IOException {
        int total = 0;
        int cur = 0;
    
        while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
            total += cur;
        }
    
        return total;
    }
    
    public final int skipBytes(int n)抛出IOException{
    int-total=0;
    int cur=0;
    而(共0个){
    总+=cur;
    }
    返回总数;
    }
    
    skipBytes()
    skip()
    具有基本相同的契约时,为什么要在循环中调用
    skip()
    ?如果以下两个条件都成立,那么以这种方式实现它将非常有意义:
    skipBytes()
    保证只在EOF上跳过比请求少的字节,并且
    skip()
    保证在可能的情况下至少跳过一个字节(就像
    read()
    那样)

    更糟糕的是,
    skip()。它只是没有承诺做到这一点,这意味着其他实现可能无法做到这一点(如果在将来的版本中进行更改,即使是Oracle one也可能在将来失败)

    为了完全安全:调用
    readBytes()
    ,如果它不起作用,则分配一个临时缓冲区,并调用
    readFully()
    (如果需要跳过任意大量数据,请在此使用循环)


    另一方面,在循环中调用
    skipBytes()
    是毫无意义的。至少在Oracle实现中是这样,因为它已经是一个循环。

    实际上,在循环中调用
    skipBytes()
    并不能完成这项工作,因为无法正确终止循环:
    skipBytes()
    可能返回0,但它没有任何意义(与
    read()
    不同,后者会根据原因返回-1或0)。更令人沮丧的是,在Oracle实现中,
    skipBytes()
    实际上在一个循环中调用
    skip()
    ,尽管两者基本上具有相同的契约。谈论糟糕的API设计。。。