最初にいくつかの背景。実際の質問に答える必要はありませんが、物事の見通しを立てるのに役立つかもしれません。
ID3タグに保存されている情報を.mp3ファイルで読み取るJava(h)でmp3ライブラリを作成しました。曲の名前、曲がリリースされたCD、トラック番号などの曲に関する情報は、.mp3ファイルの先頭にあるこのID3タグに保存されます。
ローカルハードドライブにある12,579mp3ファイルでライブラリをテストしましたが、問題なく動作します。単一の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
}