根据:
请注意,虽然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;
}
答案 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()返回可以无阻塞地读取的字节数。该数字(可以为零)与文件的总长度之间没有必要的相关性。