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

xpcnnkqh  于 11个月前  发布在  Java
关注(0)|答案(1)|浏览(201)

我试图从一个网站下载6固件压缩文件.四个文件下载罚款,我可以从下载的压缩文件中提取文件.但2压缩文件最终只有75 Kb,(而不是周围8 Mb)和损坏/无效.如果我去网站,并使用我的浏览器下载失败的文件,(通过点击下载链接),他们下载得很好.
我有一个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个特定的文件失败的意义上,我最终与一个75 kb的文件是无效的.所以我也尝试了这种方法:-

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


.但这导致了完全相同的问题. 4 zip下载OK,但其中2个文件导致75 kb的文件是无效的文件.和2个文件,未能下载使用我的代码实际上下载罚款,如果我去网站,并使用我的浏览器下载它们.
我没有得到任何错误报告,在我的应用程序在所有,所以我在亏损,以什么出错。

yhxst69z

yhxst69z1#

听起来你已经弄明白了。它没有返回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(),这会让事情变得更整洁。
另一个建议是增加缓冲区大小。现代计算机的磁盘缓冲区大小为8 MiB至4GiB。您可以看到使用更大的缓冲区(如16 kb或更高)可以提高IO性能。因此byte[] buffer = new byte[2 << 15]将给予速度提升。
如果你想获取HTTP连接的响应代码,你可以执行以下操作:

HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.connect();

int code = connection.getResponseCode();
if( code == 200 ) {
   InputStream urlStream = new BufferedInputStream( url.openStream() );
   // do the logic above
} else {
   // bad URL, or whatever!
}

相关问题