下面这段代码是下载一个http网络文件的代码,但有时候下载下来的图片是完整的,有时候下载下来的不完整,还有下载的ppt,pdf之类,也是打不开的。请大件们给指导一下,小弟感激不尽。
public String goDownLoad() throws IOException, URISyntaxException{ 
String urlPath ="http://www.yixue360.net/images/news/pic02.png";
URL _URL=new URL(urlPath);  
    HttpURLConnection con=(HttpURLConnection) _URL.openConnection();
    con.connect();
    InputStream fis=con.getInputStream();  
    
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();

//获取文件名 
    String trueurl=con.getURL().toString(); 
    String filename=trueurl.substring(trueurl.lastIndexOf('/')+1); 
this.getResponse().reset();
this.getResponse().setHeader("Content-Type", "application/octet-stream");
this.getResponse().addHeader("Content-Disposition", "attachment;filename="+ new String(filename.getBytes(), "UTF-8"));
this.getResponse().addHeader("Content-Length", "" + con.getContentLength()+10024);
SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
this.getResponse().addHeader("Date", formate.format(new Date()));
OutputStream toClient = this.getResponse().getOutputStream();
toClient.write(buffer);
toClient.flush();
toClient.close();
return null;

}java下载下载网络文件下载下载http文件

解决方案 »

  1.   

    文件大小是不是超过了你设的Content-Length
      

  2.   

    用缓冲流缓冲一下。
    要不容易出错。
    InputStream is = URLHelper.getInputStreamByUrl("http://upload.newhua.com/6/73/1291012043416.jpg");
    IOHelper.fromIputStreamToFile(is, "D:\\PP.jpg");
    public static boolean fromIputStreamToFile(InputStream is,
    String outfilepath) {
    BufferedInputStream inBuff = null;
    BufferedOutputStream outBuff = null; try {
    // 新建文件输入流并对它进行缓冲
    inBuff = new BufferedInputStream(is); // 新建文件输出流并对它进行缓冲
    outBuff = new BufferedOutputStream(
    new FileOutputStream(outfilepath)); // 缓冲数组
    byte[] b = new byte[1024 * 5];
    int len;
    while ((len = inBuff.read(b)) != -1) {
    outBuff.write(b, 0, len);
    }
    // 刷新此缓冲的输出流
    outBuff.flush();
    } catch (Exception e) {
    return false;
    } finally {
    try {
    // 关闭流
    if (inBuff != null) inBuff.close();
    if (outBuff != null)
    outBuff.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } return true;
    }
    public class URLHelper { public static String getStringByUrl(String urlstr){

    String result="";;
    try {
    InputStream is = getInputStreamByUrl(urlstr);
    result = IOHelper.fromIputStreamToString(is);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return result;
    }

    public static InputStream getInputStreamByUrl(String urlstr){
    urlstr=urlstr.startsWith("http://")?urlstr:"http://"+urlstr;
    System.out.println(urlstr);
    URL url;
    URLConnection conn;
    InputStream is = null;
    try {
    url = new URL(urlstr);
    conn = url.openConnection();
    is=conn.getInputStream();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return is;
    }
    }
      

  3.   

    this.getResponse().setHeader("Content-Type", "application/octet-stream");
            this.getResponse().addHeader("Content-Disposition", "attachment;filename="+ new String(filename.getBytes(), "UTF-8"));
            this.getResponse().addHeader("Content-Length", "" + con.getContentLength()+10024);是你设置了大小
      

  4.   


    文件大小是通过con.getContentLength()获取的,和原文件一样,我就是怕因为是这个问题,所以还在后面加了个10024。结果还是不行,把设置大小的这行代码注释掉后还是一样。请牛给支支招。小弟感激不尽。
      

  5.   

    inputStream.available()的api文档是这么说的
    Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.
    那么 byte[] buffer = new byte[fis.available()];
    这个fis.available()也就不是你想要的全部文件的长度了
      

  6.   

    byte[] buffer = new byte[fis.available()];遇到好多次人问这个问题了。上面那句代码有问题。fis.available()不是所有的文件大小
      

  7.   


    谢谢你的回答,但是我用的是 HttpURLConnection con=(HttpURLConnection) _URL.openConnection();的con.getContentLength()方法获取的,这个是正确的。其次,这个值不管我加到多大,下载的文件都不完整,一张图片也只能显示一半。我总感觉是流没输入完,还是在读的时候就没读完,请大牛指教!!
      

  8.   


    哥们,对不起啊,因为我上面有人给我说是Content-Length的问题,所以我以为你下的是现在输入的长度,所以 当我回复完后,我看了下代码发现是你说的是上面读的时候,然后下面一个人也回复我了,我才发现问题,我真没管谁是版主。 我看的只是你们的回复。都很感激。你说的就是正确的哦!
      

  9.   

     哈哈哈
    现在还是有问题呀。
    public String goDownLoad() throws IOException, URISyntaxException{ 
    String urlPath ="http://www.yixue360.net/images/news/pic02.png";
    URL _URL=new URL(urlPath);  
        HttpURLConnection con=(HttpURLConnection) _URL.openConnection();
        con.connect();
        InputStream fis=con.getInputStream();  
       
    byte[] buffer = new byte[con.getContentLength()];
    fis.read(buffer);
    fis.close();

    //获取文件名 
        String trueurl=con.getURL().toString(); 
        String filename=trueurl.substring(trueurl.lastIndexOf('/')+1); 
    this.getResponse().reset();
    this.getResponse().setHeader("Content-Type", "application/octet-stream");
    this.getResponse().addHeader("Content-Disposition", "attachment;filename="+ new String(filename.getBytes(), "UTF-8"));
    this.getResponse().addHeader("Content-Length", ""+con.getContentLength());

    SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    this.getResponse().addHeader("Date", formate.format(new Date()));
    OutputStream toClient = this.getResponse().getOutputStream();
    toClient.write(buffer);
    toClient.flush();
    toClient.close();
    return null;

    }
    这样还是不行。我呢个去,开始下了一张是好的,换了张图片又不行了。下载下来为空。
      

  10.   

    楼主根本就没读完,对于下载网络文件这种的不要一次性就以Content-Length的长度作为整个数组的大小读一次这样有可能不能读全。public String goDownLoad() throws IOException, URISyntaxException{ 
            String urlPath ="http://www.yixue360.net/images/news/pic02.png";
            URL _URL=new URL(urlPath);  
            HttpURLConnection con=(HttpURLConnection) _URL.openConnection();
            con.connect();
            InputStream fis=con.getInputStream();  
            byte[] buffer = new byte[1024];//这里开一个字节数组用来每次读取装入
             
            //获取文件名 
            String trueurl=con.getURL().toString(); 
            String filename=trueurl.substring(trueurl.lastIndexOf('/')+1); 
            this.getResponse().reset();
            this.getResponse().setHeader("Content-Type", "application/octet-stream");
            this.getResponse().addHeader("Content-Disposition", "attachment;filename="+ new String(filename.getBytes(), "UTF-8"));
            this.getResponse().addHeader("Content-Length", ""+con.getContentLength());
             
            SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            this.getResponse().addHeader("Date", formate.format(new Date()));
            OutputStream toClient = this.getResponse().getOutputStream();
            int i=-1;
            while((i=fis.read(buffer))!=-1){//在这里循环读流直到末尾保证读全
               toClient.write(buffer,0,i);
            }
            toClient.flush();
            toClient.close();
            return null;
        }
      

  11.   

    上面忘记关掉输入流了在都输出完后关闭下fis.close();
      

  12.   


    嗯,这是我拷贝代码是掉了fis.close()。那请问有什么解决办法吗? 我把这个byte[]数组的长度设为最大了还是下载不完。
      

  13.   

    谢谢各位,问题已经解决了。我这只是单纯的下载的。   OutputStream toClient = new BufferedOutputStream(this.getResponse()   
                        .getOutputStream());   
                this.getResponse().setContentType("application/octet-stream");   
                byte[] buffer = new byte[1024 * 1024 * 8];   
                int i = -1;   
                while ((i = fis.read(buffer)) != -1) {   
                    toClient.write(buffer, 0, i);   
                }
    fis.close(); 
    toClient.flush(); 
    toClient.close(); 改成这样,就OK了,下载图片,ppt,pdf都正确的。