文件下载功能是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);;
}
}