繁体   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