文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载

文件下载功能的实现思路:找到文件路径,取文件名,设置浏览器响应头,获取输入流,获取输出流,将输入流通过buffer转到输出流输出到浏览器

  1.获取要下载的文件的绝对路径

  2.获取要下载的文件名

  3.设置content-disposition响应头控制浏览器以下载的形式打开文件

  4.获取要下载的文件输入流FileInputStream

  5.创建数据缓冲区buffer

  6.通过response对象获取OutputStream流

  7.将FileInputStream流写入到buffer缓冲区

  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

文件下载注意事项:编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。


[java] view plain copy

package gacl.response.study; 

 import java.io.FileInputStream; 

 import java.io.FileNotFoundException; 

 import java.io.FileReader; 

 import java.io.IOException; 

 import java.io.InputStream; 

 import java.io.OutputStream; 

 import java.io.PrintWriter; 

 import java.net.URLEncoder; 

 import javax.servlet.ServletException; 

 import javax.servlet.http.HttpServlet; 

 import javax.servlet.http.HttpServletRequest; 

 import javax.servlet.http.HttpServletResponse; 

 /** 

 * @author gacl 

 * 文件下载 

 */ 

 public class ResponseDemo02 extends HttpServlet { 


 public void doGet(HttpServletRequest request, HttpServletResponse response) 

 throws ServletException, IOException { 

 downloadChineseFileByOutputStream(response);//下载中文文件 

 } 


 /** 

 * 下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码 

 * @param response 

 * @throws FileNotFoundException 

 * @throws IOException 

 */ 

 private void downloadChineseFileByOutputStream(HttpServletResponse response) 

 throws FileNotFoundException, IOException { 

 String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径 

 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名 

 //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码 

 response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8")); 

 InputStream in = new FileInputStream(realPath);//获取文件输入流 

 int len = 0; 

 byte[] buffer = new byte[1024]; 

 OutputStream out = response.getOutputStream(); 

 while ((len = in.read(buffer)) > 0) { 

 out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器 

 } 

 in.close(); 

 } 


 public void doPost(HttpServletRequest request, HttpServletResponse response) 

 throws ServletException, IOException { 

 doGet(request, response); 

 } 

 } 



----------java实现ftp的文件上传和下载 -------------- 

 import static org.junit.Assert.fail; 


 import java.io.File; 

 import java.io.FileInputStream; 

 import java.io.FileOutputStream; 

 import java.io.IOException; 


 import org.apache.commons.io.IOUtils; 

 import org.apache.commons.net.ftp.FTPClient; 

 import org.apache.commons.net.ftp.FTPFile; 

 import org.junit.AfterClass; 

 import org.junit.BeforeClass; 

 import org.junit.Test; 


 /** 

 * 

 * @version 创建时间:2015年12月14日 上午9:45:32 

 * 

 */ 

 public class JunitFtp { 


 private static FTPClient ftpClient; 

 private static String ftpIp = "192.168.0.229"; 

 private static String ftpUser = "ff"; 

 private static String ftpPassWord = "ff"; 

 private static String ftpPort = "21"; 

 private static String workingDirectory = "\\data"; 

 private static String localDirectory = "E:\\home\\ftp\\download"; 


 @BeforeClass 

 public static void setUpBeforeClass() throws Exception { 

 // ftp连接 

 ftpClient = new FTPClient(); 

 ftpClient.setControlEncoding("gb2312"); 

 ftpClient.connect(ftpIp, Integer.parseInt(ftpPort)); 

 ftpClient.login(ftpUser, ftpPassWord); 

 } 


 @AfterClass 

 public static void tearDownAfterClass() throws Exception { 


 ftpClient.disconnect(); 

 } 


 /** 

 *单个文件下载 

 * @throws IOException 

 * "JiaYanFei" 

 * 2015年12月14日 

 */ 

 @Test 

 public void fileDownload() throws IOException { 

 // ftpClient.setControlEncoding("gb2312"); 

 FileOutputStream fos = null; 

 try { 

 ftpClient.connect(ftpIp, Integer.parseInt(ftpPort)); 

 ftpClient.login(ftpUser, ftpPassWord); 

 ftpClient.changeWorkingDirectory(workingDirectory); 

 System.out.println("dir:" + ftpClient.printWorkingDirectory()); 

 FTPFile[] files = ftpClient.listFiles(); 

 // FTP服务器文件路径 

 String remoteFileName = "\\data\\中.txt";// 已经切换到data目录只写 中.txt 也可以 但是 写\\中.txt不行 

 String newFileName = "文.txt"; 

 // 文件下载存放路径 

 fos = new FileOutputStream(localDirectory + File.separator+ newFileName); 

 fos.flush(); 

 ftpClient.setBufferSize(1024); 

 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 

 if (ftpClient.retrieveFile(remoteFileName, fos)) { 

 System.out.println(" 文件下载成功。。"); 

 } else { 

 System.out.println(" 文件下载失败。。"); 

 fail("下载失败"); 

 } 


 } catch (Exception e) { 

 e.printStackTrace(); 

 } finally { 

 IOUtils.closeQuietly(fos); 

 ftpClient.disconnect(); 

 } 


 } 


 @Test 

 public void fileUpload() throws IOException { 

 FileInputStream fis = null; 

 try { 

 ftpClient.connect(ftpIp, Integer.parseInt(ftpPort)); 

 ftpClient.login(ftpUser, ftpPassWord); 

 ftpClient.changeWorkingDirectory("/data"); 


 fis = new FileInputStream(new File("E:\\home\\ftp\\data\\o.txt")); 

 if (ftpClient.storeFile("/data/backFile3.txt", fis)) {// /backFile3.txt backFile3.txt也可以 

 System.out.println("上传成功!"); 

 } else { 

 System.out.println("上传失败"); 

 fail("上传失败"); 

 } 

 } finally { 

 IOUtils.closeQuietly(fis); 

 ftpClient.disconnect(); 

 } 


 } 






 /** 

 *目录下载 

 * @throws IOException 

 * 2015年12月14日 

 */ 

 @Test 

 public void downloadDirectory() throws IOException { 

 downloadDirectory("\\data" ,localDirectory+ "\\data"); 

 } 



 /** 

 *目录递归下载 

 * @param basePath 

 * @param localPath 

 * @throws IOException 

 * 2015年12月14日 

 */ 

 public void downloadDirectory(String basePath, String localPath) throws IOException{ 

 ftpClient.changeWorkingDirectory(basePath); 

 System.out.println(ftpClient.printWorkingDirectory()); 

 FTPFile[] files = ftpClient.listFiles(); 

 if (0 == files.length) {// 目录为空 创建空目录 

 System.out.println("dir name: " +localPath ); 

 new File(localPath ).mkdirs(); 

 return; 

 } 

 File file = null; 

 for(FTPFile f:files){ 

 if(f.isDirectory()){ 

 downloadDirectory(basePath + File.separator + f.getName(), localPath + File.separator + f.getName()); 

 }else{ 

 file = new File(localPath);//先判断本地目录是否存在 --不存在则创建 

 if(!file.exists()){ 

 file.mkdirs(); 

 } 

 FileOutputStream fos = new FileOutputStream( localPath + File.separator + f.getName()); 

 fos.flush(); 

 ftpClient.setBufferSize(1024); 

 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 

 System.out.println("fileName: " + f.getName()); 

 if (ftpClient.retrieveFile(basePath + File.separator +f.getName(), fos)) { 

 System.out.println(" 文件下载成功。。"); 

 } else { 

 System.out.println(" 文件下载失败。。"); 

 fail("下载失败"); 

 } 

 } 


 } 


 } 


 } 



------------------------------------java socket实现文件的上传和下载------------- 

import Java.io.BufferedInputStream; 

import java.io.DataInputStream; 

import java.io.DataOutputStream; 

import java.io.File; 

import java.io.FileInputStream; 

import java.io.FileOutputStream; 

import java.io.IOException; 

import java.io.InputStream; 

import java.io.OutputStream; 

import java.net.ServerSocket; 

import java.net.Socket; 


public class ServerScoket { 

//服务器端 

int port= 8822;//设置的端口号 

public void UpFile(){//接受客户端上传的文件,并保存 

 try { 

ServerSocket server= new ServerSocket(port); 

 while(true){ 

 Socket socket = server.accept(); 

 DataInputStream is = new DataInputStream(socket.getInputStream()); 

 OutputStream os = socket.getOutputStream(); 

 //1、得到文件名 

 String filename="E:\\"; 

 filename += is.readUTF(); 


 System.out.println("新生成的文件名为:"+filename); 

 FileOutputStream fos = new FileOutputStream(filename); 

 byte[] b = new byte[1024]; 

 int length = 0; 

 while((length=is.read(b))!=-1){ 

 //2、把socket输入流写到文件输出流中去 

 fos.write(b, 0, length); 

 } 

 fos.flush(); 

 fos.close(); 

 is.close(); 

 socket.close(); 

 } 

 } catch (IOException e) { 

 // TODO Auto-generated catch block 

 e.printStackTrace(); 

 } 


} 



public void DownFile(String filePath){ 

//接受客户端的下载请求,将本地文件传输给客户端 

 try { 

 while (true) { 

ServerSocket server= new ServerSocket(port); 

 // 选择进行传输的文件 

 File fi = new File(filePath); 

 System.out.println("文件长度:" + (int) fi.length()); 

 // public Socket accept() throws 

 // IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。 

 Socket socket = server.accept(); 

 System.out.println("建立socket链接"); 

 /* DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 

 dis.readByte(); 

 */ 

 DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath))); 

 DataOutputStream ps = new DataOutputStream(socket.getOutputStream()); 

 //将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。 

 ps.writeUTF(fi.getName()); 

 System.out.println(fi.getName()); 

 ps.flush(); 

 int bufferSize = 8192; 

 byte[] buf = new byte[bufferSize]; 

 while (true) { 

 int read = 0; 

 if (fis != null) { 

 read = fis.read(buf); 

 } 

 if (read == -1) { 

 break; 

 } 

 ps.write(buf, 0, read); 

 } 

 ps.flush(); 

 // 注意关闭socket链接哦,不然客户端会等待server的数据过来, 

 // 直到socket超时,导致数据不完整。 

 fis.close(); 

 socket.close(); 

 System.out.println("文件传输完成"); 

 } 

 } catch (Exception e) { 

 e.printStackTrace(); 

 } 

} 

public static void main(String arg[]) { 

 //String filepath="D:\\test.txt"; 

 new ServerScoket().UpFile(); 

 } 


} 


******************************************************************************************************************************************************** 


import java.io.BufferedInputStream; 

import java.io.DataInputStream; 

import java.io.DataOutputStream; 

import java.io.File; 

import java.io.FileInputStream; 

import java.io.FileOutputStream; 

import java.io.IOException; 

import java.io.OutputStream; 

import java.NET.Socket; 


public class ClientScoket { 

//客户端 

private String ip = "localhost";// 设置成服务器IP 

 private int port = 8822;//设置端口号 

 public void UpFile(String filePath){ 

 //上传文件,将本地文件传输到服务器端 

 try { 

 Socket socket = new Socket(ip,port); 

 while (true) { 

 // 选择进行传输的文件 

 File fi = new File(filePath); 

 System.out.println("文件长度:" + (int) fi.length()); 

 /* DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream())); 

 dis.readByte(); 

 */ 

 DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath))); 

 DataOutputStream ps = new DataOutputStream(socket.getOutputStream()); 

 //将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。 

 ps.writeUTF(fi.getName()); 

 ps.flush(); 


 int bufferSize = 8192; 

 byte[] buf = new byte[bufferSize]; 

 while (true) { 

 int read = 0; 

 if (fis != null) { 

 read = fis.read(buf); 

 } 


 if (read == -1) { 

 break; 

 } 

 ps.write(buf, 0, read); 

 } 

 ps.flush(); 

 // 注意关闭socket链接哦,不然客户端会等待server的数据过来, 

 // 直到socket超时,导致数据不完整。 

 fis.close(); 

 socket.close(); 

 System.out.println("文件传输完成"); 

 } 

 } catch (Exception e) { 

 e.printStackTrace(); 

 } 

} 


public void DownFile(){ 

//从服务器端下载文件 

try { 

 Socket socket = new Socket(ip,port); 

 while(true){ 

 DataInputStream is = new DataInputStream(socket.getInputStream()); 

 OutputStream os = socket.getOutputStream(); 

 //1、得到文件名 

 String filename="E:\\"; 

 filename += is.readUTF(); 


 System.out.println("新生成的文件名为:"+filename); 

 FileOutputStream fos = new FileOutputStream(filename); 

 byte[] b = new byte[1024]; 

 int length = 0; 

 while((length=is.read(b))!=-1){ 

 //2、把socket输入流写到文件输出流中去 

 fos.write(b, 0, length); 

 } 

 fos.flush(); 

 fos.close(); 

 is.close(); 

 socket.close(); 

 } 


 } catch (IOException e) { 

 // TODO Auto-generated catch block 

 e.printStackTrace(); 

 } 

} 

public static void main(String arg[]) { 

String filepath="D:\\test.txt"; 

 new ClientScoket().UpFile(filepath);; 

 } 

}