java上传文件跟批量下载文件(转)
2014-02-11 11:05
369 查看
最近的项目中涉及到文件的上传跟下载的问题,就自己所涉及到的方面做出如下表述。
首先是文件上传部分,项目的要求是通用性较好,所以只需要传入目标路径即可。参数的传递通过Form表单传值,在目标路径下新建一个File类型的文件,然后通过流的方式将需要上传的文件写入新建的文件中。此方法适用于web开发过程中上传文档类的文件,如果你文件过大请研究ftp相关的知识,笔者所接触的ftp传文件限于C#中,这里不做表述。具体代码如下:
第二部分是关于文件批量下载的文档。根据客户的观点有上传就要下载的需求,一开始也做了相关的开发,结果发现下载时的文件全部存在服务器端,跟需求不一致。仔细推敲了下代码原来自己写的有问题,在客户端是选择文件的存储路径,然后将文件下载,其实只是实现了本地的迁移,并没有在把文件下载到客户端。后来的想法是把文件打包下载,用FileOutputStream,实现下载的问题,可是如果下载的文件中含有中文字符,就会出现乱码。不得已百度了下,原来是编码的问题,使用java自带的文件输出类不能解决压缩文件中文件名乱码的问题。解决方法:使用ant.jar包,创建压缩文件时,可以设置文件的编码格式,文件名乱码的问题就解决了。由于笔者在开发过程中数据库中有文件的路径,所以下列文件的文件路径的获取是查询得到。
具体的解决代码如下:
引用ant.jar包中的FileOutputStream类
打包下载多个文件的思路就是在服务端创建一个新的压缩文件(zip格式),然后将下载的多个文件写入该压缩包中,然后以流的形式输出压缩文件写到客户端,实现下载功能。
单个文件的下载直接下载文件即可,使用java自带的FileOutputStream就能实现,可以从上面的批量下载中提取单个文件下载的方法。
涉及到文件名称编码的问题,这里提供一个格式化中文字符串的方法。
首先是文件上传部分,项目的要求是通用性较好,所以只需要传入目标路径即可。参数的传递通过Form表单传值,在目标路径下新建一个File类型的文件,然后通过流的方式将需要上传的文件写入新建的文件中。此方法适用于web开发过程中上传文档类的文件,如果你文件过大请研究ftp相关的知识,笔者所接触的ftp传文件限于C#中,这里不做表述。具体代码如下:
public void fileUpload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String filePath = new String(); request.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=GB2312"); try { DiskFileItemFactory factory = new DiskFileItemFactory(); //设置缓存中最大允许缓存为2M factory.setSizeThreshold(2 * 1024 * 1024); ServletFileUpload upload = new ServletFileUpload(factory); //解决中文文件名为乱码的问题 upload.setHeaderEncoding("UTF-8"); List<FileItem> fileList = upload.parseRequest(request); Iterator iter = fileList.iterator(); String newFileName = ""; while (iter.hasNext()) { //获取文件 FileItem fileItem = (FileItem)iter.next(); //获取文件上传的路径 String typeName = fileItem.getFieldName(); if(("destPath").equals(typeName)) { filePath = fileItem.getString("utf-8"); } if(("filename").equals(typeName)) { newFileName = fileItem.getString("utf-8"); } String fileName = new String(); if (!fileItem.isFormField()) { String name = fileItem.getName(); if(StringUtil.isNullOrEmpty(name)) { continue; } fileName = name; fileName = fileName.substring(fileName.lastIndexOf("\\") + 1); File file = new File(filePath); if(!file.exists()) { file.mkdirs(); } //向指定的路径写文件 if(newFileName.length()>0) { fileName = newFileName; } fileItem.write(new File(filePath, fileName)); } } } catch (Exception ex) { throw new ServletException("上传文件失败!", ex); } }
第二部分是关于文件批量下载的文档。根据客户的观点有上传就要下载的需求,一开始也做了相关的开发,结果发现下载时的文件全部存在服务器端,跟需求不一致。仔细推敲了下代码原来自己写的有问题,在客户端是选择文件的存储路径,然后将文件下载,其实只是实现了本地的迁移,并没有在把文件下载到客户端。后来的想法是把文件打包下载,用FileOutputStream,实现下载的问题,可是如果下载的文件中含有中文字符,就会出现乱码。不得已百度了下,原来是编码的问题,使用java自带的文件输出类不能解决压缩文件中文件名乱码的问题。解决方法:使用ant.jar包,创建压缩文件时,可以设置文件的编码格式,文件名乱码的问题就解决了。由于笔者在开发过程中数据库中有文件的路径,所以下列文件的文件路径的获取是查询得到。
具体的解决代码如下:
引用ant.jar包中的FileOutputStream类
import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream;
打包下载多个文件的思路就是在服务端创建一个新的压缩文件(zip格式),然后将下载的多个文件写入该压缩包中,然后以流的形式输出压缩文件写到客户端,实现下载功能。
public void downloadFiles(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String docId = new String(request.getParameter("docId").getBytes("ISO-8859-1"), "UTF-8"); String downloadType = new String(request.getParameter("downloadType").getBytes("ISO-8859-1"), "UTF-8"); Document doc = null; try { doc = getFilePath(docId); //此方法获取文件的路径,这个不显示 } catch (SQLException ex) { ex.printStackTrace(); } List<Element> elements = doc.getRootElement().elements(); List<File> files = new ArrayList<File>(); int index = 0; long fileLength = 0; for(Element ele : elements) { String filePath = FormatUtil.tryGetItemText(ele, "FILE_PATH", "") + FormatUtil.tryGetItemText(ele, "FILE_NAME", ""); File file = new File(filePath); files.add(file); fileLength += file.length(); index++; } String fileName = UUID.randomUUID().toString() + ".zip"; //在服务器端创建打包下载的临时文件 String outFilePath = "C:\\" + fileName; File file = new File(outFilePath); //文件输出流 FileOutputStream outStream = new FileOutputStream(file); //压缩流 ZipOutputStream toClient = new ZipOutputStream(outStream); toClient.setEncoding("gbk"); zipFile(files, toClient); toClient.close(); outStream.close(); this.downloadZip(file, response); } /** * 压缩文件列表中的文件 * @param files * @param outputStream * @throws IOException */ public static void zipFile(List files, ZipOutputStream outputStream) throws IOException,ServletException { try { int size = files.size(); //压缩列表中的文件 for(int i = 0; i < size; i++) { File file = (File) files.get(i); zipFile(file, outputStream); } } catch(IOException e) { throw e; } } /** * 将文件写入到zip文件中 * @param inputFile * @param outputstream * @throws Exception */ public static void zipFile(File inputFile, ZipOutputStream outputstream) throws IOException,ServletException { try{ if(inputFile.exists()) { if(inputFile.isFile()) { FileInputStream inStream = new FileInputStream(inputFile); BufferedInputStream bInStream = new BufferedInputStream(inStream); ZipEntry entry = new ZipEntry(inputFile.getName()); outputstream.putNextEntry(entry); final int MAX_BYTE = 10 * 1024 *1024; //最大的流为10M long streamTotal = 0; //接受流的容量 int streamNum = 0; //流需要分开的数量 int leaveByte = 0; //文件剩下的字符数 byte[] inOutbyte; //byte数组接受文件的数据 streamTotal = bInStream.available(); //通过available方法取得流的最大字符数 streamNum = (int)Math.floor(streamTotal / MAX_BYTE); //取得流文件需要分开的数量 leaveByte = (int)streamTotal % MAX_BYTE; //分开文件之后,剩余的数量 if (streamNum > 0) { for(int j = 0; j < streamNum; ++j) { inOutbyte = new byte[MAX_BYTE]; //读入流,保存在byte数组 bInStream.read(inOutbyte, 0, MAX_BYTE); outputstream.write(inOutbyte, 0, MAX_BYTE); //写出流 } } //写出剩下的流数据 inOutbyte = new byte[leaveByte]; bInStream.read(inOutbyte, 0, leaveByte); outputstream.setEncoding("gbk");//解决中文文件名乱码 outputstream.write(inOutbyte); outputstream.closeEntry(); //Closes the current ZIP entry and positions the stream for writing the next entry bInStream.close(); //关闭 inStream.close(); } } else { throw new ServletException("文件不存在!"); } } catch(IOException e) { throw e; } } /** * 下载打包的文件 * @param file * @param response */ public void downloadZip(File file,HttpServletResponse response) { try { // 以流的形式下载文件。 BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath())); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" + file.getName()); toClient.write(buffer); toClient.flush(); toClient.close(); file.delete(); //将生成的服务器端文件删除 } catch (IOException ex) { ex.printStackTrace(); } }
单个文件的下载直接下载文件即可,使用java自带的FileOutputStream就能实现,可以从上面的批量下载中提取单个文件下载的方法。
涉及到文件名称编码的问题,这里提供一个格式化中文字符串的方法。
public static String toUtf8String(String s){ StringBuffer sb = new StringBuffer(); for (int i = 0;i < s.length(); i++){ char c = s.charAt(i); if (c >= 0 && c <= 255) { sb.append(c); } else{ byte[] b; try { b = Character.toString(c).getBytes("utf-8"); } catch (Exception ex) { b = new byte[0]; } for (int j = 0; j < b.length; j++) { int k = b[j]; if (k < 0) k += 256; sb.append("%" + Integer.toHexString(k).toUpperCase()); } } } return sb.toString(); }
相关文章推荐
- java 上传文件和批量下载文件(转载)
- 【Java】 java上传文件跟批量下载文件
- JAVA上传批量下载文件
- JAVA SFTP文件上传、下载及批量下载实例
- java上传文件跟批量下载文件
- JAVA SFTP文件上传、下载及批量下载
- java上传文件跟批量下载文件
- java上传文件跟批量下载文件
- Java 实现文件批量文件打包下载
- JAVA实现FTP文件上传下载文件
- Java文件上传下载 源码
- 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器
- java_web 学习记录(六):文件上传和下载
- Java文件下载和上传源代码
- JAVA WEB 批量文件下载
- java文件批量打包下载
- ftp上传和下载文件的java实现
- 用Java实现FTP批量大文件上传下载(五)
- JAVA中FTP文件上传下载
- 用java在web环境下上传和下载文件的技巧