小弟一直是做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();
}
}
以前这段代码都没有问题,这向天突然出现问题了,下载下来的文件变为空文件了,真是太奇怪了,不知道是程序写的有问题,还是其他原因,大伙有这方面的经历吗?
代码如下:
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();
}
}
以前这段代码都没有问题,这向天突然出现问题了,下载下来的文件变为空文件了,真是太奇怪了,不知道是程序写的有问题,还是其他原因,大伙有这方面的经历吗?
我试了下,还是不行;这上代码是上半年写的,一直都没有问题;最近突然下载文件下来是空的,经过仔细分析问题就出在这里,如果代码没有问题,那会不会有其他什么原因呢?
如果服务器发来的字节流没有作任何标记,只是在发完一次数据后flush(),则在客户端可以用inputStream.available()来判断流的长度。
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)会出抛出异常的原因,在此谢过,祝大家新年快乐!
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);
} 这么写才没问题,这块 代码段的意思是 增加 流的缓冲区 大小 ,可以写 文件速度加快 ,这种例子网上很多的
2 使用流 将下载的文件 用 InputStream 读进来
3 在 OutputStream 中 通过 InputStream 读的 流 ,使用 OutputStream 来写 需要下载的文件.
4 关闭那两个流 就完了 . 用不着 什么 smartupload 还要引包,直接 写Servlet 不就完了.
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;
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);
}
}
}}
谢谢朋友的回复,对于你说的这段代码
while ((nSize = in.read(buf)) > 0)
{
fw.write(buf, 0 ,nSize);
} 我之前试过,仍然不行,问题不在于比较是否等于-1或大于0这里,而在于只要我连续两次调用了in.read(buf)就会地抛出异常.我确实对java不熟悉,也临时用到了,在网上找了一段代码,在jdk api里看了下帮助手册,然后修改了一下代码.不过还是要感谢大家的指导,问题解决了就好,呵呵!