0

Webサイトからすべてのバイトを読み取ろうとしていますが、すべてのバイトを取得できないと思います。バイト配列の長さに高い値を指定します。このメソッドを使用しましたが、常に例外が返されます。

コードは次のとおりです。

DataInputStream dis = new DataInputStream(s2.getInputStream());

byte[] bytes = new byte[900000];

// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
    && (numRead=dis.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
}

// Ensure all the bytes have been read in
if (offset < bytes.length) {
    throw new IOException("Could not completely read website");
}
out.write(bytes);

編集されたバージョン:

ByteArrayOutputStream bais = new ByteArrayOutputStream();
InputStream is = null;
try {
    is = s2.getInputStream();
    byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time.
    int n;
    while ( (n = is.read(byteChunk)) > 0 ) {
        bais.write(byteChunk, 0, n);
    }
}
catch (IOException e) {
    System.err.printf ("Failed while reading bytes");
    e.printStackTrace ();
    // Perform any other exception handling that's appropriate.
}
finally {
    if (is != null) { is.close(); }
}
byte[] asd = bais.toByteArray();
out.write(asd);
4

2 に答える 2

3

これが問題です:

if (offset < bytes.length)

元のデータが900,000バイトを超える場合にのみトリガーされます。応答がそれ未満で完全に完了した場合read()、ストリームの終了を示すために-1を正しく返します。

が等しい場合offset bytes.length、実際には例外をスローする必要があります。これは、データが切り捨てられた可能性があることを示しています:)

900,000の価値をどこから得たのかは明確ではありません、気をつけてください...

生のストリームを使い続けたい場合は、GuavaByteStreams.toByteArray方法を使用してすべてのデータを読み取ることをお勧めします。または、ループを繰り返し、小さなバッファに読み込んで、ByteArrayOutputStream反復ごとにに書き込むこともできます。

于 2012-10-17T17:13:29.967 に答える
1

これはあなたの特定の質問に答えるものではないことを私は理解しています。ただし、 HttpClientなどのライブラリが存在し、デバッグ/プロファイルされている場合などは、この種のことを実際に手動でコーディングすることはありません。

たとえば、流暢なインターフェースの使用方法は次のとおりです

Request.Get("http://targethost/homepage").execute().returnContent();

JSoupは、HTMLの取得とスクレイピングを扱う場合の代替手段です。

于 2012-10-17T17:06:32.293 に答える