簡體   English   中英

使用Java二進制文件下載的文件已損壞

[英]Files downloaded as Binary with Java are corrupted

我已經編寫了一個下載器,該下載器應可用於下載文本文件以及圖像。 因此,我將文件下載為二進制文件。 許多下載都能很好地運行,但是文本文件和許多圖像文件的某些部分已損壞。 錯誤總是出現在相同的文件和相同的位置(只要我可以在分析文本文件時知道)。 我使用以下代碼進行下載:

    public File downloadFile(HttpURLConnection connection) {
        return writeFileDataToFile(getFileData(connection));
    }     

    //downloads the data of the file and returns the content as string
    private List<Byte> getFileData(HttpURLConnection connection) {
        List<Byte> fileData = new ArrayList<>();

        try (InputStream input = connection.getInputStream()) {
            byte[] fileChunk = new byte[8*1024];
            int bytesRead;

            do {
                bytesRead = input.read(fileChunk);
                if (bytesRead != -1) {
                    fileData.addAll(Bytes.asList(fileChunk));
                    fileChunk = new byte[8*1024];
                }
            } while (bytesRead != -1);

            return fileData;
        } catch (IOException e) {
            System.out.println("Receiving file at " + url.toString() + " failed");
            System.exit(1);
            return null; //shouldn't be reached
        }
    }

    //writes data to the file
    private File writeFileDataToFile(List<Byte> fileData) {

        if (!this.file.exists()) {
            try {
                this.file.getParentFile().mkdirs();
                this.file.createNewFile();
            } catch (IOException e) {
                System.out.println("Error while creating file at " + file.getPath());
                System.exit(1);
            }
        }

        try (OutputStream output = new FileOutputStream(file)) {
            output.write(Bytes.toArray(fileData));
            return file;
        } catch (IOException e) {
            System.out.println("Error while accessing file at " + file.getPath());
            System.exit(1);
            return null;
        }
    }

我建議您不要通過字節列表,因為您是從數組中創建字節列表,然后再將其返回到字節數組,這並不是很有效。

此外,您錯誤地假定了塊大小(不一定是8192字節)。

您為什么不做以下事情:

private File writeFileDataToFile(HttpURLConnection connection) {
    if (!this.file.exists()) {
        try {
            this.file.getParentFile().mkdirs();
            //this.file.createNewFile(); // not needed, will be created at FileOutputStream
        } catch (IOException e) {
            System.out.println("Error while creating file at " + file.getPath());
            //System.exit(1);
            // instead do a throw of error or return null
            throw new YourException(message);
        }
    }
    OutputStream output = null;
    InputStream input = null;
    try {
      output = new FileOutputStream(file):
      input = connection.getInputStream();
      byte[] fileChunk = new byte[8*1024];
      int bytesRead;
      while ((bytesRead = input.read(fileChunk )) != -1) {
         output.write(fileChunk , 0, bytesRead);
      }
      return file;
    } catch (IOException e) {
      System.out.println("Receiving file at " + url.toString() + " failed");
      // System.exit(1); // you should avoid such exit
      // instead do a throw of error or return null
      throw new YourException(message);
    } finally {
      if (input != null) {
        try {
           input.close();
        } catch (Execption e2) {} // ignore
      }
      if (output != null) {
        try {
           output.close();
        } catch (Execption e2) {} // ignore
      }
    }
}

失敗是將整個fileChunk Array添加到文件數據中,即使它沒有被讀取操作完全填充。

固定:

//downloads the data of the file and returns the content as string
private List<Byte> getFileData(HttpURLConnection connection) {
    List<Byte> fileData = new ArrayList<>();

    try (InputStream input = connection.getInputStream()) {
        byte[] fileChunk = new byte[8*1024];
        int bytesRead;

        do {
            bytesRead = input.read(fileChunk);
            if (bytesRead != -1) {
                fileData.addAll(Bytes.asList(Arrays.copyOf(fileChunk, bytesRead)));
            }
        } while (bytesRead != -1);

        return fileData;
    } catch (IOException e) {
        System.out.println("Receiving file at " + url.toString() + " failed");
        System.exit(1);
        return null; //shouldn't be reached
    }
}

相關變化正在變化的地方

if (bytesRead != -1) {
    fileData.addAll(Bytes.asList(fileChunk));
    fileChunk = new byte[8*1024];
}

進入

 if (bytesRead != -1) {
    fileData.addAll(Bytes.asList(Arrays.copyOf(fileChunk, bytesRead)));
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM