来自oracle的InputStream.available()和读取文件的完整备注

时间:2014-08-29 14:18:14

标签: java android file-io inputstream bufferedreader

根据:

  

请注意,虽然InputStream的某些实现将返回   流中的总字节数,很多都不会。永远不会   正确使用此方法的返回值来分配缓冲区   旨在保存此流中的所有数据。

从:

http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available%28%29

和本说明

In particular, code of the form

int n = in.available();
byte buf = new byte[n];
in.read(buf); 

is not guaranteed to read all of the remaining bytes from the given input stream.

http://docs.oracle.com/javase/8/docs/technotes/guides/io/troubleshooting.html

剂量是否意味着使用below function导致不完全读取文件?

/**
 * Reads a file from /raw/res/ and returns it as a byte array
 * @param res Resources instance for Mosembro
 * @param resourceId ID of resource (ex: R.raw.resource_name)
 * @return byte[] if successful, null otherwise
 */
public static byte[] readRawByteArray(Resources res, int resourceId)
{
    InputStream is = null;
    byte[] raw = new byte[] {};
    try {
        is = res.openRawResource(resourceId);
        raw = new byte[is.available()];
        is.read(raw);
    }
    catch (IOException e) {
        e.printStackTrace();
        raw = null;
    }
    finally {
        try {
            is.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    return raw;
}

2 个答案:

答案 0 :(得分:1)

是的,它不一定全部读完。与RandomAccessFile.read(byte[])相反,与RandomAccessFile.readFully(byte[])相对。此外,代码实际上物理上读取0个字节。

它可能只读取第一个块,如果它是像文件系统那样的慢速设备。

  

原则:   通常,底层系统软件正在读取该文件   缓冲,所以你已经在内存中有几个块,并且   有时候已经进一步阅读该软件读取asynchrone   块,以及,如果尝试读取超过系统的数量   已阅读。

因此,一般来说,软件中有一个块的读循环,并且在读取时定期读取操作会阻塞,直到物理读取充分缓冲。

为了避免非阻塞,您需要这样做:

InputStream is = res.openRawResource(resourceId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (;;) {
    // Read bytes until no longer available:
    for (;;) {
        int n = is.available();
        if (n == 0) {
            break;
        }
        byte[] part = new byte[n];
        int nread = is.read(part);
        assert nread == n;
        baos.write(part, 0, nread);
    }
    // Still a probably blocking read:
    byte[] part = new byte[128];
    int nread = is.read(part);
    if (nread <= 0) {
        break; // End of file
    }
    baos.write(part, 0, nread);
}
return baos.toByteArray();

现在,在复制该代码之前,立即执行阻塞读取循环。我看不到使用available()的优势,除非您在阅读其他内容时可以对部分数据执行某些操作。

答案 1 :(得分:1)

available()返回可以无阻塞地读取的字节数。该数字(可以为零)与文件的总长度之间没有必要的相关性。