Java InputStream.available()和从oracle完全读取文件注释
根据: 注意,虽然InputStream的一些实现将返回 流中的总字节数,许多字节不会。从来都不是 更正以使用此方法的返回值分配缓冲区 用于保存此流中的所有数据 发件人: 这张纸条呢Java InputStream.available()和从oracle完全读取文件注释,java,android,file-io,inputstream,bufferedreader,Java,Android,File Io,Inputstream,Bufferedreader,根据: 注意,虽然InputStream的一些实现将返回 流中的总字节数,许多字节不会。从来都不是 更正以使用此方法的返回值分配缓冲区 用于保存此流中的所有数据 发件人: 这张纸条呢 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 th
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.
这是否意味着使用下面的函数
会导致无法完全读取文件
/**
* 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;
}
是的,它不一定读全部。类似于
RandomAccessFile.read(字节[])
而不是RandomAccessFile.readFully(字节[])
。此外,代码实际读取0字节
如果它是像文件系统这样的慢速设备,它可能只读取第一个块
原则:
文件通常由底层系统软件读取
缓冲,所以内存中已经有几个块
有时已经在进一步阅读了。软件读取异步
块,如果试图读取的数据超过系统的数据量,则块
已经读过了
因此,一般来说,在软件中有一个块的读取循环,并定期在一次读取操作块,直到物理读取缓冲区足够
要实现无阻塞,您需要执行以下操作:
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();
InputStream is=res.openrawsource(resourceId);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
对于(;;){
//读取字节直到不再可用:
对于(;;){
int n=is.available();
如果(n==0){
打破
}
字节[]部分=新字节[n];
int nread=is.read(部分);
断言nread==n;
编写(第0部分,nread);
}
//仍然是一个可能的阻塞读取:
字节[]部分=新字节[128];
int nread=is.read(部分);
如果(nread可用()返回无阻塞情况下可以读取的字节数。该数字(可以为零)与文件的总长度之间没有必要的相关性。+1用于您的答案,但代码实际读取0字节。
我不这样认为,我也看不到我的问题与读取阻塞或n有任何联系on-blocking.有一件事我没有说:available()
返回无阻塞(=已缓冲)可读取的字节数。因此available()
在任何时候都可以产生0,即在最开始的时候。我的论点是:一个人可以进行阻塞读取,而不会受到惩罚。只有在做更多的工作时,比如在循环中读取N个文件available()
可能是值得的。我希望有人会来,希望把这个问题说得更清楚一点。@mmlooo联系在于hat是available()返回内容的定义。将它用作流的总长度是对它的滥用。