使用 Java 从网站下载 zip 文件时出现问题

问题描述 投票:0回答:1

我正在尝试从网站下载 6 个固件 zip 文件。其中四个文件下载良好,我可以从下载的 zip 中提取文件。但其中 2 个 zip 文件最终只有 75Kb(而不是大约 8Mb)并且已损坏/无效。如果我访问该网站并使用浏览器下载失败的文件(通过单击下载链接),它们下载得很好。

我有一个 grails/groovy 应用程序,但我使用 Java 进行下载。

我尝试了两种不同的方法来做到这一点。第一个是:-

    URL url = new URL("https://thewebsite.com/filestore/thefile.zip");
    BufferedInputStream bis = new BufferedInputStream(url.openStream());
    FileOutputStream fis = new FileOutputStream("c:\mydownloadedfile\thefile.zip");
    byte[] buffer = new byte[1024];
    int count = 0;
    while ((count = bis.read(buffer, 0, 1024)) != -1) {
        fis.write(buffer, 0, count);
    }
    fis.close();
    bis.close();

对于网站上的 4 个 zip 文件来说这很好,但有 2 个特定文件失败了,因为我最终得到了一个无效的 75kb 文件。所以我也尝试了这个方法:-

    Files.copy(
            new URL("https://thewebsite.com/filestore/thefile.zip").openStream(),
            Paths.get("c:\mydownloadedfile\thefile.zip"))

...但这导致了完全相同的问题。 4 个 zip 文件下载正常,但其中 2 个文件生成了 75kb 的文件,这些文件是无效文件。如果我访问该网站并使用浏览器下载,使用我的代码无法下载的 2 个文件实际上可以正常下载。

我的应用程序中根本没有报告任何错误,所以我不知道出了什么问题。

java groovy grails
1个回答
0
投票

听起来你已经明白了。它不会返回 200。但是,代码中确实存在一个可能在某个时刻触发的错误。您基本上所做的编码相当于“不冲水并离开座位”。更具体地说,如果抛出异常,这些流将不会关闭,文件句柄将保持打开状态。而且,如果您使用任何缓冲流(即

BufferedOutputStream
),您可能会在内存中留下未写入文件的字节(在您的代码中,您没有这样做,但如果它发生变化,缺陷可能会蔓延).

    URL url = new URL("https://thewebsite.com/filestore/thefile.zip");
    try( BufferedInputStream bis = new BufferedInputStream(url.openStream()) ) {
       try( FileOutputStream fis = new FileOutputStream("c:\mydownloadedfile\thefile.zip") ) {
          byte[] buffer = new byte[1024];
          int count = 0;
          while ((count = bis.read(buffer, 0, 1024)) != -1) {
             fis.write(buffer, 0, count);
          }
       }
    }

如果您改用 try-resource 语法,那么即使抛出异常,Java 也会适当地为您关闭这些流,这样就不会泄漏资源。而且,如果您使用类似

BufferedOutputStream
之类的东西来防止流丢失内存中剩余的数据,它将刷新缓冲区。另外,您不必写
fis.close()
bis.close()
这会让事情变得更整洁。

另一个建议是增大缓冲区大小。现代计算机配备 8MiB 到 4GiB 的磁盘缓冲区大小。通过使用更大的缓冲区(例如 16kb 或更高),您可以看到 IO 性能得到提高。所以

byte[] buffer = new byte[2 << 15]
会提高你的速度。

© www.soinside.com 2019 - 2024. All rights reserved.