文件下载在浏览器中有效但不能以编程方式进行

时间:2015-08-23 01:25:22

标签: java file download

我在以编程方式下载某些文件时遇到了一些问题,但同样的下载在浏览器中运行良好。

下载开始并下载文件,但是大小错误且所有信息都已损坏。它应该只是一个XML文件,但是当我尝试打开文件时会发生这种情况。

enter image description here

以下是代码:

URL只是一个带有链接的常量,我更改了两个参数。

        Calendar dataFuturo = Calendar.getInstance();
        dataFuturo.add(Calendar.DATE, 10);
        String urlFormatada = String.format(URL, StringUtils.dateParaString(new Date(), StringUtils.DEFAULT_DATE),
                StringUtils.dateParaString(dataFuturo.getTime(), StringUtils.DEFAULT_DATE));
        System.out.println(urlFormatada);
        System.out.println(StringUtils.dateParaString(new Date(), StringUtils.DEFAULT_DATE));
        System.out.println(StringUtils.dateParaString(dataFuturo.getTime(), StringUtils.DEFAULT_DATE));
        final String diretorio = SettingsUtil.getMessage(SettingsUtil.DIRETORIO_BACKUP) + "teste.xml";
        URL url = new URL(URL);
        InputStream is = null;
        FileOutputStream fos = null;
        FileUtils.copyURLToFile(url, new File(diretorio));
        System.out.println("Finished");

我尝试以多种方式下载文件,但结果总是一样。

另一次尝试:

        Calendar dataFuturo = Calendar.getInstance();
        dataFuturo.add(Calendar.DATE, 10);
        String urlFormatada = String.format(URL, StringUtils.dateParaString(new Date(), StringUtils.DEFAULT_DATE),
                StringUtils.dateParaString(dataFuturo.getTime(), StringUtils.DEFAULT_DATE));
        System.out.println(urlFormatada);
        System.out.println(StringUtils.dateParaString(new Date(), StringUtils.DEFAULT_DATE));
        System.out.println(StringUtils.dateParaString(dataFuturo.getTime(), StringUtils.DEFAULT_DATE));
        final String diretorio = SettingsUtil.getMessage(SettingsUtil.DIRETORIO_BACKUP) + "teste.xml";
        URL url = new URL(URL); //The file that you want to download
        InputStream is = null;
        FileOutputStream fos = null;

        try {
            URLConnection urlConn = url.openConnection();//connect
            urlConn.setDoInput(true);
            urlConn.setDoOutput(true);
            urlConn.setUseCaches(false);
            urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
            urlConn.connect();
            System.out.println("type: " + urlConn.getContentType());
            System.out.println("total size: " + urlConn.getContentLength());
            is = urlConn.getInputStream();               //get connection inputstream
            fos = new FileOutputStream(diretorio);   //open outputstream to local file

            byte[] buffer = new byte[4096];              //declare 4KB buffer
            int len;

            //while we have availble data, continue downloading and storing to local file
            while ((len = is.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } finally {
                if (fos != null) {
                    fos.close();
                }
            }
        }

        System.out.println("Finished");

2 个答案:

答案 0 :(得分:0)

  • 摆脱setDoOutput(true)。这会将请求从GET更改为POST,这会破坏与浏览器正在执行的操作的兼容性。
  • 检查内容编码响应标头。它看起来像压缩数据。如果您不想处理该问题,请更改Accept-encoding请求标头以将其排除。
  • 你也可以摆脱connect()行。它隐含在getInputStream()以及您正在调用的其他几种方法中。

答案 1 :(得分:-1)

问题:

您是以GET还是POST来呼叫该网页?如果是get,则必须注释掉urlConn.setDoInput(true);urlConn.setDoOutput(true);行,并使用openStream()代替getInputStream()
但如果它是post,那么不需要传递任何数据,那么任何标题呢?设置content-length?!

第一

while((l=is.read(buff))!=-1){/*instead of >0*/fos.write(buffer, 0, len);}

其次,将文件初始化为

fos=new FileOutputStream(diretorio);
fos.getChannel().truncate(0);

最后,确保刷新文件

try{...
}finaly{fos.flush();fos.close()}

或者更好地使用try(<closable>){...}

压缩数据,您可以使用GZIPInputStream而不是默认/纯InputStream

来读取数据
GZIPInputStream is=new GZIPInputStream(urlConn.getInputStream());