首先是一些背景。它不需要回答实际问题,但也许它会有助于正确看待事情。
我在 java (h) 中编写了一个 mp3 库,它读取存储在 .mp3 文件中 ID3 标记中的信息。有关歌曲的信息,如歌曲名称、歌曲发行的 CD、曲目编号等,都存储在 .mp3 文件开头的这个 ID3 标签中。
我已经在位于我本地硬盘上的 12,579 个 mp3 文件上测试了该库,并且它运行良好。没有一个 IO 错误。
当我在 mp3 文件位于 Web 服务器上执行相同的操作时,我收到一个 IO 错误。好吧,实际上不是错误。实际上,这是 InputStream 的 read(byte[]) 方法的行为不同。
下面的示例将说明问题,当我尝试从 mp3 文件中读取图像文件(.jpg、.gif、.png 等)时会发生此问题。
// read bytes from an .mp3 file on your local hard drive
// reading from an input stream created this way works flawlessly
InputStream inputStream = new FileInputStream("song.mp3");
// read bytes from an .mp3 file given by a url
// reading from an input stream created this way fails every time.
URL url = "http://localhost/song.mp3");
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection();
httpConnection.connect();
InputStream inputStream = url.openStream();
int size = 25000; // size of the image file
byte[] buffer = new byte[size];
int numBytesRead = inputStream.read(buffer);
if (numBytesRead != buffer.length)
throw new IOException("Error reading the bytes into the buffer. Expected " + buffer.length + " bytes but got " + numBytesRead + " bytes");
所以,我的观察是:调用 inputStream.read(buffer); 当输入流是 FileInputStream 时,总是读取全部字节数。但是当我使用从 http 连接获得的输入流时,它只会读取部分数量。
因此我的问题是:一般来说,我不能假设 InputStream 的 read(byte[]) 方法会阻塞,直到读取了全部字节数(或达到 EOF)?也就是说,我是否假设 read(byte[]) 方法的行为不正确,并且我刚刚幸运地使用了 FileInputStream?
InputStream.read(byte[]) 的正确和一般行为是否需要将调用置于循环中并继续读取字节,直到读取所需的字节数或达到 EOF?类似于下面的代码:
int size = 25000;
byte[] buffer = new byte[size];
int numBytesRead = 0;
int totalBytesRead = 0;
while (totalBytesRead != size && numBytesRead != -1)
{
numBytesRead = inputStream.read(buffer);
totalBytesRead += numBytesRead
}