小弟一直是做C++的,最近工作需求要求写一段java代码,实现http下载文件的功能,我在网上找了一段,以前用一直没有事,可是这向天突然出现问题了,大家去招啊.
代码如下:
boolean GetImpowerFile(String url, String param, String path)
{
//获取授权文件
URL httpurl = null;
HttpURLConnection httpConn = null;
  try
  {
   httpurl = new URL(url);
   httpConn = (HttpURLConnection)httpurl.openConnection();       
   httpConn.setDoOutput(true);
   httpConn.setDoInput(true);
   PrintWriter outs = new PrintWriter(httpConn.getOutputStream());
   outs.print(param);
   outs.flush();
   outs.close();
//这里发送请求,返回都没有问题,我用抓包工具看过.
   BufferedInputStream in = new BufferedInputStream(httpConn.getInputStream());    
   //设置授权文件路径    
   int nIndex = path.indexOf("tomcat");  
   path = path.substring(0, nIndex);
 path += "server\\bin\\avnet\\profile\\KAVNET.dat.new";
   FileOutputStream  fw=new FileOutputStream(path);
   int len = in.available();   //在这里缓存里的字节数返回永远都是0,以前这里就能正常返回大小.
   byte buf[] = new byte[len];
   in.read(buf);
   fw.write(buf, 0 ,len);
 fw.flush();
 fw.close(); 
 in.close();
  
 return true;

  }catch(Exception e)
  {
     return false;
  }
  finally
  {
    if(httpConn!=null)
      httpConn.disconnect();      
  }
}
以前这段代码都没有问题,这向天突然出现问题了,下载下来的文件变为空文件了,真是太奇怪了,不知道是程序写的有问题,还是其他原因,大伙有这方面的经历吗?

解决方案 »

  1.   

    在available行之前加一句int firstChar = in.read();试试
      

  2.   

    我也有过,最后用jspSmartUpload控件写的下载页面。这个问题也没解决,关注一下!
      

  3.   

    to dracularking :
     我试了下,还是不行;这上代码是上半年写的,一直都没有问题;最近突然下载文件下来是空的,经过仔细分析问题就出在这里,如果代码没有问题,那会不会有其他什么原因呢?
      

  4.   

    有可能是服务器端发生了变化。
    如果服务器发来的字节流没有作任何标记,只是在发完一次数据后flush(),则在客户端可以用inputStream.available()来判断流的长度。
      

  5.   

    经过仔细查找资料,在该行代码处:
    int   len   =   in.available();       
    调用available()函数有安全隐患,jdk api中描述:
    中文:Returns the number of bytes that can be read from this input stream without blocking.
    英文:返回在不发生阻塞的情况下,可读取的字节数;
    隐患:问题就处在不发生阻塞的情况下,在网络环境中可能存在阻塞,很多时候会导致返回失效,结果为0;所以在网络环境切不能够使用这种方式获取缓存区大小.解决办法:
    1.获取缓存区大小采取获取返回的http的Content-Length的大小;
    2.将上术代码改为:
    byte buf[] = new byte[10240];
    int nSize = 0;
    .....
    nSize = in.read(buf);
    fw.write(buf, 0 ,nSize);.....
    上面只能免费满足我的要求,因为我下载的文件不超过1K;
    最完整的方案是:
    byte buf[] = new byte[1024];
    int nSize = 0;
    .....
    while ((nSize = in.read(buf)) != -1)
    {
       fw.write(buf, 0 ,nSize);
    }
    ....
     
    不过不知道是什么原因,只要第二次调用in.read(buf)就会出现异常,由于时间问题以及本人对java不是很了解,就不深入研究了,先暂且满足我下载不超过1K文件的要求.希望java版块的大牛人能够告诉小弟一下,为什么两次调用in.read(buf)会出抛出异常的原因,在此谢过,祝大家新年快乐!
      

  6.   

    挖哈哈!!!  你代码 都写错了~  还玩个六 , 楼上的代码段  
    byte   buf[]   =   new   byte[1024]; 
    int   nSize   =   0; 
    ..... 
    while   ((nSize   =   in.read(buf))   !=   -1) 

          fw.write(buf,   0   ,nSize); 

    中的 
    while   ((nSize   =   in.read(buf))   !=   -1) 

          fw.write(buf,   0   ,nSize); 
    } 应写为  
    while   ((nSize   =   in.read(buf))  >0) 

          fw.write(buf,   0   ,nSize); 
    } 这么写才没问题,这块 代码段的意思是 增加 流的缓冲区 大小 ,可以写 文件速度加快 ,这种例子网上很多的
      

  7.   

    其实本身 你在 研究下载的问题 上 已经 进 了一个误区 , 首先你要了解 java 实现文件下载的原理是什么 :  1 在 Servlet 中 通过 response 对象  获取  OutputStream
    2 使用流 将下载的文件 用 InputStream 读进来  
    3 在 OutputStream  中 通过 InputStream  读的 流 ,使用 OutputStream 来写 需要下载的文件.
    4 关闭那两个流 就完了  .  用不着 什么 smartupload 还要引包,直接 写Servlet  不就完了. 
      

  8.   

    这是用struts中写下载的,随便写的不知道对你有没用
    SmartUploadForm smartUploadForm=(SmartUploadForm)form;
            FormFile file1 = smartUploadForm.getUpLoad();
            
            System.out.println("file===="+file1);
            InputStream is = file1.getInputStream(); //读入文件        response.reset();     
            response.setContentType("bin");   
            response.addHeader("Content-Disposition","attachment;filename=test.xls"); 
            byte[]   buffer;   
            int   length=(new   Long(file1.getFileSize()).intValue());   
            buffer=new   byte[length];   
            System.out.println("length==="+length);
            BufferedInputStream bis = new BufferedInputStream(is);
            FileOutputStream out1=new FileOutputStream("c://test.xls");
            while (bis.read(buffer) > 0) {
                out1.write(buffer);
            }
            out1.flush();
            ServletOutputStream out = response.getOutputStream(); 
            while (bis.read(buffer) > 0) {
                out.write(buffer);
            }
            out.flush();
            bis.close();
            is.close();
            return null;
      

  9.   

    给你一段我写的文件下载 :  
    public class ReportExportFileServlet extends HttpServlet {
         public ReportExportFileServlet() {
    super();
    }
            public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
                    //要下载的文件名, 这个文件名 为文件 头的名字 
            String fileName = TimeUtil.getCurrentlyTimeSecond("", "", "") +".zip"; //  这步 是必不可少的 ,因为这步解决了 文件头的乱码问题 !!!
    String fileExactName = URLEncoder.encode(fileName, "UTF-8");
    //设置文件头
    response.setHeader("Content-disposition","attachment; filename=" + fileExactName);
    //设置文本类型为下载            
            response.setContentType("application/x-msdownload");
            downLoadFile(response.getOutputStream()fileName );
            }        private void downLoadFile(OutputStream out,String inputZipFile) {
        
         FileInputStream in = null;
        
         try {
    in = new FileInputStream(inputZipFile); // 读入文件
    out.flush();
    int aRead = 0;
    while ((aRead = in.read()) != -1 & in != null) {
    out.write(aRead);
    }
    out.flush();
    } catch (Throwable e) {
    // log.error("FileDownload doGet() IO error!",e);
    } finally {
    try {
    in.close();
    out.close();
    } catch (Throwable e) {
    // log.error("FileDownload doGet() IO close error!",e);
    }
    }
        }}
      

  10.   

    to billwindows :
    谢谢朋友的回复,对于你说的这段代码
    while       ((nSize       =       in.read(buf))     > 0)   
    {   
                fw.write(buf,       0       ,nSize);   
    }   我之前试过,仍然不行,问题不在于比较是否等于-1或大于0这里,而在于只要我连续两次调用了in.read(buf)就会地抛出异常.我确实对java不熟悉,也临时用到了,在网上找了一段代码,在jdk api里看了下帮助手册,然后修改了一下代码.不过还是要感谢大家的指导,问题解决了就好,呵呵!
      

  11.   

    嘎嘎 ~oo~ ,俺是看见你不会 java 才写 那么详细的 ,解决了就好 ~oo~