IOException: поток закрыт - PullRequest
       10

IOException: поток закрыт

0 голосов
/ 06 ноября 2018

Этот код создает закрытый поток, и я не могу понять, почему. Он встроен в Apache Cloudstack, и каждый раз, когда я пытаюсь загрузить огромные файлы (например, 20 ГБ и более), возникает исключение.

Из-за getMessage () в блоке catch я даже не уверен, генерирует ли RandomAccessFile () IOException или getResponseBodyAsStream ().

К сожалению, очень сложно перекомпилировать и протестировать этот фрагмент кода, поэтому я буду очень признателен за любые подсказки, что может пойти не так.

Я попытался немного уменьшить его, но вы можете найти полную версию здесь: https://github.com/apache/cloudstack/blob/1d05fead49f5c856257a741b07122f5633d2e359/core/src/main/java/com/cloud/storage/template/HttpTemplateDownloader.java#L184

try (InputStream in = request.getResponseBodyAsStream();
    RandomAccessFile out = new RandomAccessFile(file, "rw"); ) {
        out.seek(localFileSize);

        if (copyBytes(file, in, out)) return 0;

        } finally { /* in.close() and out.close() */ }
            return totalBytes;
        } catch (HttpException hte) {
            status = TemplateDownloader.Status.UNRECOVERABLE_ERROR;
            errorString = hte.getMessage();
        } catch (IOException ioe) {
            status = TemplateDownloader.Status.UNRECOVERABLE_ERROR;
            errorString = ioe.getMessage();
        } finally {
            if (status == Status.UNRECOVERABLE_ERROR && 
                file.exists() && !file.isDirectory()) {
                file.delete();
            }
            request.releaseConnection();
            if (callback != null) {
                callback.downloadComplete(status);
            }
        }

private boolean copyBytes(File file, 
                          InputStream in, 
                          RandomAccessFile out) throws IOException {
    int bytes;
    byte[] block = new byte[CHUNK_SIZE];
    long offset = 0;
    boolean done = false;
    VerifyFormat verifyFormat = new VerifyFormat(file);
    status = Status.IN_PROGRESS;

    while (!done && status != Status.ABORTED && offset <= remoteSize) {
       if ((bytes = in.read(block, 0, CHUNK_SIZE)) > -1) {
           offset = writeBlock(bytes, out, block, offset);
           if (!verifyFormat.isVerifiedFormat() && 
              (offset >= 1048576 || offset >= remoteSize)) { 
                  //let's check format after we get 1MB or full file
                  verifyFormat.invoke();
                  if (verifyFormat.isInvalid()) return true;
           }
            } else {
                done = true;
            }
        }
        out.getFD().sync();
        return false;
    }
...