HttpServletRequestWrapper应用(二):包装文件上传请求

包装文件上传请求

目的:通过HttpServletRequestWrapper包装文件上传请求,模块化文件上传处理,提高代码复用率,简化开发。



文件上传采用的是commons-fileupload文件上传组件1.2.1版(同时需要commons-io-1.4.jar)。

考虑到将来有可能扩展支持其他上传组件,所以设计了以下两个接口,分别用于抽象请求处理和文件操作。



文件操作抽象层:



Java代码
/**
* 之所以设计这个接口,是为了符合针对接口编程的设计原则,将来可以扩充支持其他上传组件的具体实现类型
*/
public interface FormFile {

/**
* 获得文件尺寸
*/
public long getFileSize();
/**
* 获得文件的名称
*/
public String getFileName();

/**
* 获得文件的字节数组形式的数据
*/
public byte[] getFileData()
throws FileNotFoundException, IOException;

/**
* 获得文件输入流
*/
public InputStream getInputStream()
throws FileNotFoundException, IOException;

/**
* 返回文件的类型,如“image/gif”,即“Content-Type”字段的值部分。
*/
public String getContentType();

/**
* 销毁上传文件
*/
public void destroy();
}

/**
* 之所以设计这个接口,是为了符合针对接口编程的设计原则,将来可以扩充支持其他上传组件的具体实现类型
*/
public interface FormFile {

/**
* 获得文件尺寸
*/
public long getFileSize();
/**
* 获得文件的名称
*/
public String getFileName();

/**
* 获得文件的字节数组形式的数据
*/
public byte[] getFileData()
throws FileNotFoundException, IOException;

/**
* 获得文件输入流
*/
public InputStream getInputStream()
throws FileNotFoundException, IOException;

/**
* 返回文件的类型,如“image/gif”,即“Content-Type”字段的值部分。
*/
public String getContentType();

/**
* 销毁上传文件
*/
public void destroy();
}
多媒体请求处理抽象层,用于解析请求,将文件参数封装成FormFile类型,保存在请求包装器中,稍后情看具体实现:



Java代码
/**
* 处理文件上传请求
*/
public interface MultipartRequestHandler {
/**
* 解析文件上传请求
*/
public MultipartRequestWrapper handleRequest(HttpServletRequest request) throws ServletException;
}

/**
* 处理文件上传请求
*/
public interface MultipartRequestHandler {
/**
* 解析文件上传请求
*/
public MultipartRequestWrapper handleRequest(HttpServletRequest request) throws ServletException;
}

接着来看针对commons-fileupload组件的FormFile实现。commons-fileupload组件将所有参数封装成FileItem类型,以List返回。所以这里通过包装FileItem对象来实现FormFile:



Java代码
/**
* 针对commons-fileupload的FormFile实现,持有FileItem对象的引用,通过FileItem的方法实现 FormFile 的方法
*/
public class CommonsUploadFormFile implements FormFile {

FileItem fileItem;
InputStream inputstream;
//通过构造函数持有FileItem对象的引用
public CommonsUploadFormFile(FileItem fileItem) {
this.fileItem = fileItem;
}

public byte[] getFileData() throws FileNotFoundException, IOException {
return fileItem.get();
}

public String getFileName() {
return getBaseFileName(fileItem.getName());
}

public long getFileSize() {
return fileItem.getSize();
}

public InputStream getInputStream() throws FileNotFoundException,IOException {
return fileItem.getInputStream();
}

public String getContentType() {
return fileItem.getContentType();
}

public void destroy() {
fileItem.delete();
}

/**
* FileItem的getName()方法获得的是上传文件在客户机上存放的具体路径如:
* C:\Documents and Settings\shenlin\桌面\21534822.jpg
* 本方法用于取得该路径中的基本文件名称,即21534822.jpg
*/
protected String getBaseFileName(String filePath) {
//按照路径构造File对象,通过File的getName()方法获得文件的名称
String fileName = new File(filePath).getName();
//检查是否成功获得文件名称,如果仍然你包含":","\\"和"\",那么利用字符串截取获得文件名称
int colonIndex = fileName.indexOf(":");
if (colonIndex == -1) {
colonIndex = fileName.indexOf("\\\\");
}
int backslashIndex = fileName.lastIndexOf("\\");
if ((colonIndex > -1) && (backslashIndex > -1)) {
fileName = fileName.substring(backslashIndex + 1);
System.out.println(fileName);
}
return fileName;
}
}

/**
* 针对commons-fileupload的FormFile实现,持有FileItem对象的引用,通过FileItem的方法实现 FormFile 的方法
*/
public class CommonsUploadFormFile implements FormFile {

FileItem fileItem;
InputStream inputstream;
//通过构造函数持有FileItem对象的引用
public CommonsUploadFormFile(FileItem fileItem) {
this.fileItem = fileItem;
}

public byte[] getFileData() throws FileNotFoundException, IOException {
return fileItem.get();
}

public String getFileName() {
return getBaseFileName(fileItem.getName());
}

public long getFileSize() {
return fileItem.getSize();
}

public InputStream getInputStream() throws FileNotFoundException,IOException {
return fileItem.getInputStream();
}

public String getContentType() {
return fileItem.getContentType();
}

public void destroy() {
fileItem.delete();
}

/**
* FileItem的getName()方法获得的是上传文件在客户机上存放的具体路径如:
* C:\Documents and Settings\shenlin\桌面\21534822.jpg
* 本方法用于取得该路径中的基本文件名称,即21534822.jpg
*/
protected String getBaseFileName(String filePath) {
//按照路径构造File对象,通过File的getName()方法获得文件的名称
String fileName = new File(filePath).getName();
//检查是否成功获得文件名称,如果仍然你包含":","\\"和"\",那么利用字符串截取获得文件名称
int colonIndex = fileName.indexOf(":");
if (colonIndex == -1) {
colonIndex = fileName.indexOf("\\\\");
}
int backslashIndex = fileName.lastIndexOf("\\");
if ((colonIndex > -1) && (backslashIndex > -1)) {
fileName = fileName.substring(backslashIndex + 1);
System.out.println(fileName);
}
return fileName;
}
}
针对commons-fileupload组件实现MultipartRequestHandler接口:



Java代码
/**
* 通过commons-fileupload解析文件上传请求,并将解析得到的参数保存在包装了当前请求MultipartRequestWrapper对象中
*/
public class CommonsUploadMultipartRequestHandler implements MultipartRequestHandler {

/**默认最大尺寸限制*/
public static final long DEFAULT_SIZE_MAX = 250 * 1024 * 1024;

/** 小于指定尺寸的文件直接保存在内存中,否则保存在临时文件夹*/
public static final int DEFAULT_SIZE_THRESHOLD = 256 * 1024;

/**
* 解析文件上传请求
*/
public MultipartRequestWrapper handleRequest(HttpServletRequest request) throws ServletException {
DiskFileUpload upload = new DiskFileUpload();
// 最大尺寸限制
upload.setSizeMax(DEFAULT_SIZE_MAX);
// 小于指定尺寸的文件直接保存在内存中,否则保存在临时文件夹
upload.setSizeThreshold(DEFAULT_SIZE_THRESHOLD);
// 用于存放解析出来的请求参数
List items = null;
try {
items = upload.parseRequest(request);
} catch (DiskFileUpload.SizeLimitExceededException e) {
throw new ServletException(e);
} catch (FileUploadException e) {
throw new ServletException(e);
}

MultipartRequestWrapper req = new MultipartRequestWrapper(request);

// 文本类型数据以Stirng类型添加到包装器中,文件以FormFile类型保存在包装器中
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
addTextParameter(req, item);
} else {
addFileParameter(req, item);
}
}
return req;
}

/**
* 添加文本参数到包装器中
*/
protected void addTextParameter(MultipartRequestWrapper request,
FileItem item) {
// 得到方法用于返回表单字段元素的name属性值 Name
String name = item.getFieldName();
// 用于保存text的value值
String value = null;
String encoding = request.getCharacterEncoding();
try {
if (encoding == null) {
value = item.getString("ISO-8859-1");
} else {
value = item.getString(encoding);
}
} catch (java.io.UnsupportedEncodingException uee) {
value = item.getString();
}
// 添加参数到包装器
request.setParameter(name, value);
}

/**
* 添加文件参数到包装器中
*/
protected void addFileParameter(MultipartRequestWrapper request,FileItem item) {
FormFile formFile = new CommonsUploadFormFile(item);
// 得到方法用于返回表单字段元素的name属性值 Name
String name = item.getFieldName();
request.setParameter(name, formFile);
}
}

/**
* 通过commons-fileupload解析文件上传请求,并将解析得到的参数保存在包装了当前请求MultipartRequestWrapper对象中
*/
public class CommonsUploadMultipartRequestHandler implements MultipartRequestHandler {

/**默认最大尺寸限制*/
public static final long DEFAULT_SIZE_MAX = 250 * 1024 * 1024;

/** 小于指定尺寸的文件直接保存在内存中,否则保存在临时文件夹*/
public static final int DEFAULT_SIZE_THRESHOLD = 256 * 1024;

/**
* 解析文件上传请求
*/
public MultipartRequestWrapper handleRequest(HttpServletRequest request) throws ServletException {
DiskFileUpload upload = new DiskFileUpload();
// 最大尺寸限制
upload.setSizeMax(DEFAULT_SIZE_MAX);
// 小于指定尺寸的文件直接保存在内存中,否则保存在临时文件夹
upload.setSizeThreshold(DEFAULT_SIZE_THRESHOLD);
// 用于存放解析出来的请求参数
List items = null;
try {
items = upload.parseRequest(request);
} catch (DiskFileUpload.SizeLimitExceededException e) {
throw new ServletException(e);
} catch (FileUploadException e) {
throw new ServletException(e);
}

MultipartRequestWrapper req = new MultipartRequestWrapper(request);

// 文本类型数据以Stirng类型添加到包装器中,文件以FormFile类型保存在包装器中
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
addTextParameter(req, item);
} else {
addFileParameter(req, item);
}
}
return req;
}

/**
* 添加文本参数到包装器中
*/
protected void addTextParameter(MultipartRequestWrapper request,
FileItem item) {
// 得到方法用于返回表单字段元素的name属性值 Name
String name = item.getFieldName();
// 用于保存text的value值
String value = null;
String encoding = request.getCharacterEncoding();
try {
if (encoding == null) {
value = item.getString("ISO-8859-1");
} else {
value = item.getString(encoding);
}
} catch (java.io.UnsupportedEncodingException uee) {
value = item.getString();
}
// 添加参数到包装器
request.setParameter(name, value);
}

/**
* 添加文件参数到包装器中
*/
protected void addFileParameter(MultipartRequestWrapper request,FileItem item) {
FormFile formFile = new CommonsUploadFormFile(item);
// 得到方法用于返回表单字段元素的name属性值 Name
String name = item.getFieldName();
request.setParameter(name, formFile);
}
}


接着我们来看请求包装器的实现,由于HttpServletRequest没有提供返回文件类型参数的方法,只好自己增加两个,感觉挺不爽的,在JSP或servlet中必须将请求类型装换成MultipartRequestWrapper才可以使用:



Java代码
/**
* 包装HttpServletRequest,针对multipart requests 重新实现getParameter,以方便获得普通表单域参数(文本)。
* 文件参数和
*/
public class MultipartRequestWrapper extends HttpServletRequestWrapper {
/**
* 用于存放multipart request的参数
*/
protected Map parameters;

/**
* 持有被装饰者(HttpServletRequest对象)引用,初始化用于存放multipart request的参数的Map
*/
public MultipartRequestWrapper(HttpServletRequest request) {
super(request);
this.parameters = new HashMap();
}

/**
* 保存文本参数
*/
public void setParameter(String name, String value) {
String[] oldArray = (String[]) parameters.get(name);
if (oldArray == null) {
oldArray = new String[0];
}
String[] newArray = new String[oldArray.length + 1];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
newArray[oldArray.length] = value;
parameters.put(name, newArray);
}

/**
* 保存文件参数
* @param name
* @param value
*/
public void setParameter(String name, FormFile value) {
FormFile[] oldArray = (FormFile[]) parameters.get(name);
if (oldArray == null) {
oldArray = new FormFile[0];
}
FormFile[] newArray = new FormFile[oldArray.length + 1];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
newArray[oldArray.length] = value;
parameters.put(name, newArray);
}

/**
* 通过包装器存放参数的Map对象,如果参数有多个值返回第一个值。
*/
public String getParameter(String name) {
String value = null;
String[] valueArray = (String[]) parameters.get(name);
if ((valueArray != null) && (valueArray.length > 0)) {
value = valueArray[0];
}
return value;
}

/**
* 通过包装器存放参数的Map对象获得参数,如果不为null ,以String[]形式返回。
*/
public String[] getParameterValues(String name) {
String[] value = (String[]) parameters.get(name);
return value;
}

/**
* HttpServletRequest没有提供返回文件的方法,自己增加一个,
* 在servlet或jsp中必须把请求类型转换成MultipartRequestWrapper才可以访问该方法
* 通过包装器存放参数的Map对象,如果参数有多个值返回第一个值。
*/
public FormFile getFormFile(String name) {
FormFile value = null;
FormFile[] valueArray = (FormFile[]) parameters.get(name);
if ((valueArray != null) && (valueArray.length > 0)) {
value = valueArray[0];
}
return value;
}

/**
* HttpServletRequest没有提供返回文件的方法,自己增加一个,
* 在servlet或jsp中必须把请求类型转换成MultipartRequestWrapper才可以访问该方法
* 通过包装器存放参数的Map对象获得参数,如果不为null ,以FormFile[]形式返回。
*/
public FormFile[] getFormFiles(String name) {
FormFile[] value = (FormFile[]) parameters.get(name);
return value;
}

/**
* 通过包装器存放参数的Map对象 获得参数名称枚举
*/
public Enumeration getParameterNames() {
Vector list = new Vector();
Collection multipartParams = parameters.keySet();
Iterator iterator = multipartParams.iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return Collections.enumeration(list);
}

/**
* 返回存放参数的Map对象
*/
public Map getParameterMap() {
return parameters;
}
}

/**
* 包装HttpServletRequest,针对multipart requests 重新实现getParameter,以方便获得普通表单域参数(文本)。
* 文件参数和
*/
public class MultipartRequestWrapper extends HttpServletRequestWrapper {
/**
* 用于存放multipart request的参数
*/
protected Map parameters;

/**
* 持有被装饰者(HttpServletRequest对象)引用,初始化用于存放multipart request的参数的Map
*/
public MultipartRequestWrapper(HttpServletRequest request) {
super(request);
this.parameters = new HashMap();
}

/**
* 保存文本参数
*/
public void setParameter(String name, String value) {
String[] oldArray = (String[]) parameters.get(name);
if (oldArray == null) {
oldArray = new String[0];
}
String[] newArray = new String[oldArray.length + 1];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
newArray[oldArray.length] = value;
parameters.put(name, newArray);
}

/**
* 保存文件参数
* @param name
* @param value
*/
public void setParameter(String name, FormFile value) {
FormFile[] oldArray = (FormFile[]) parameters.get(name);
if (oldArray == null) {
oldArray = new FormFile[0];
}
FormFile[] newArray = new FormFile[oldArray.length + 1];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
newArray[oldArray.length] = value;
parameters.put(name, newArray);
}

/**
* 通过包装器存放参数的Map对象,如果参数有多个值返回第一个值。
*/
public String getParameter(String name) {
String value = null;
String[] valueArray = (String[]) parameters.get(name);
if ((valueArray != null) && (valueArray.length > 0)) {
value = valueArray[0];
}
return value;
}

/**
* 通过包装器存放参数的Map对象获得参数,如果不为null ,以String[]形式返回。
*/
public String[] getParameterValues(String name) {
String[] value = (String[]) parameters.get(name);
return value;
}

/**
* HttpServletRequest没有提供返回文件的方法,自己增加一个,
* 在servlet或jsp中必须把请求类型转换成MultipartRequestWrapper才可以访问该方法
* 通过包装器存放参数的Map对象,如果参数有多个值返回第一个值。
*/
public FormFile getFormFile(String name) {
FormFile value = null;
FormFile[] valueArray = (FormFile[]) parameters.get(name);
if ((valueArray != null) && (valueArray.length > 0)) {
value = valueArray[0];
}
return value;
}

/**
* HttpServletRequest没有提供返回文件的方法,自己增加一个,
* 在servlet或jsp中必须把请求类型转换成MultipartRequestWrapper才可以访问该方法
* 通过包装器存放参数的Map对象获得参数,如果不为null ,以FormFile[]形式返回。
*/
public FormFile[] getFormFiles(String name) {
FormFile[] value = (FormFile[]) parameters.get(name);
return value;
}

/**
* 通过包装器存放参数的Map对象 获得参数名称枚举
*/
public Enumeration getParameterNames() {
Vector list = new Vector();
Collection multipartParams = parameters.keySet();
Iterator iterator = multipartParams.iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return Collections.enumeration(list);
}

/**
* 返回存放参数的Map对象
*/
public Map getParameterMap() {
return parameters;
}
}
下面就该选择合适的地点来执行请求的处理了,我选择在过滤器中,比较简单。请看filter.ContentTypeFilter的doFilter()方法实现(部分代码是应用一中处理中文乱码用的):



Java代码
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//设置请求响应字符编码
request.setCharacterEncoding(charset);
response.setCharacterEncoding(charset);

HttpServletRequest req = (HttpServletRequest)request;
//包装请求,在getParameter方法中增加字符编码转换逻辑
if(req.getMethod().equalsIgnoreCase("get"))
{
req = new GetHttpServletRequestWrapper(req,charset);
}
//处理多媒体类型的请求,并使用MultipartRequestWrapper包装请求,包装器作为请求对象传递给目标servlet或JSP
if(req.getMethod().equalsIgnoreCase("post") && req.getHeader("Content-Type").contains("multipart/form-data"))
{
req = new CommonsUploadMultipartRequestHandler().handleRequest(req);
}

System.out.println("----请求被"+config.getFilterName()+"过滤");
//执行下一个过滤器(如果有的话,否则执行目标servlet)
chain.doFilter(req, response);

System.out.println("----响应被"+config.getFilterName()+"过滤");

}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//设置请求响应字符编码
request.setCharacterEncoding(charset);
response.setCharacterEncoding(charset);

HttpServletRequest req = (HttpServletRequest)request;
//包装请求,在getParameter方法中增加字符编码转换逻辑
if(req.getMethod().equalsIgnoreCase("get"))
{
req = new GetHttpServletRequestWrapper(req,charset);
}
//处理多媒体类型的请求,并使用MultipartRequestWrapper包装请求,包装器作为请求对象传递给目标servlet或JSP
if(req.getMethod().equalsIgnoreCase("post") && req.getHeader("Content-Type").contains("multipart/form-data"))
{
req = new CommonsUploadMultipartRequestHandler().handleRequest(req);
}

System.out.println("----请求被"+config.getFilterName()+"过滤");
//执行下一个过滤器(如果有的话,否则执行目标servlet)
chain.doFilter(req, response);

System.out.println("----响应被"+config.getFilterName()+"过滤");

}
最后请看测试servlet代码,获得文本参数直接使用ServletRequest接口定义的getParameter(name)等方法就可以了,获得文件就不得不将请求类型装换成MultipartRequestWrapper,然后调用FormFile getFormFile(String name)和FormFile[] getFormFiles (String name)方法了:



Java代码
/**
* 文件上传测试
*/
public class FileUpload extends HttpServlet {
public static final String FileDIR = "/upload/";
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request转换成MultipartRequestWrapper类型
MultipartRequestWrapper req = (MultipartRequestWrapper)request;
//获得上传文件的真实绝对路径
String saveRealPath = request.getRealPath(FileDIR);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
//打印表单文本域text1的值
String text1 = req.getParameter("text1");
FormFile file1 = req.getFormFile("file1");
//保存file1
DoUploadFile.saveFile(file1,saveRealPath);
//根据file1保存的相对路径,构造图片标签,用于显示图片
out.print(text1);
out.print(":</br>");
out.print("<img src=\"");
out.print(request.getContextPath());
out.print(FileDIR);
out.print(file1.getFileName());
out.print("\" /></br>");

//打印表单文本域text2的值
String text2 = req.getParameter("text2");
out.print(text2);
out.print(":</br>");

//叫file2的表单文件域有两个,所以需要循环处理
FormFile[] file2 = req.getFormFiles("file2");
for(FormFile file:file2)
{
DoUploadFile.saveFile(file,saveRealPath);
out.print("<img src=\"");
out.print(request.getContextPath());
out.print(FileDIR);
out.print(file.getFileName());
out.print("\" /></br>");
}
out.flush();
out.close();
}
}

/**
* 文件上传测试
*/
public class FileUpload extends HttpServlet {
public static final String FileDIR = "/upload/";
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request转换成MultipartRequestWrapper类型
MultipartRequestWrapper req = (MultipartRequestWrapper)request;
//获得上传文件的真实绝对路径
String saveRealPath = request.getRealPath(FileDIR);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
//打印表单文本域text1的值
String text1 = req.getParameter("text1");
FormFile file1 = req.getFormFile("file1");
//保存file1
DoUploadFile.saveFile(file1,saveRealPath);
//根据file1保存的相对路径,构造图片标签,用于显示图片
out.print(text1);
out.print(":</br>");
out.print("<img src=\"");
out.print(request.getContextPath());
out.print(FileDIR);
out.print(file1.getFileName());
out.print("\" /></br>");

//打印表单文本域text2的值
String text2 = req.getParameter("text2");
out.print(text2);
out.print(":</br>");

//叫file2的表单文件域有两个,所以需要循环处理
FormFile[] file2 = req.getFormFiles("file2");
for(FormFile file:file2)
{
DoUploadFile.saveFile(file,saveRealPath);
out.print("<img src=\"");
out.print(request.getContextPath());
out.print(FileDIR);
out.print(file.getFileName());
out.print("\" /></br>");
}
out.flush();
out.close();
}
}
文件保存工具类:



Java代码
/**
* 用于实现文件的上传的工具类
*/
public final class DoUploadFile {
/**
* 依据传递参数上传文件
* @param formfile 上传的文件
* @param filePath 文件保存路径
* @throws IOException
*/
public static void saveFile(FormFile formfile,String filePath)
throws IOException {

String fileName = formfile.getFileName();

File dir = new File(filePath);
if(!dir.exists()) dir.mkdir();

// 获取上传文件的输入流
InputStream in = new BufferedInputStream(formfile.getInputStream());

// 实例化文件空壳(根据 filePath 路径名字符串和 fileName 路径名字符串创建一个新 File 实例)
File fileSaved = new File(filePath, fileName);

// 创建二进制文件输出流
OutputStream os = new FileOutputStream(fileSaved);

int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();

// 关闭文件流
os.close();
in.close();
}
}

/**
* 用于实现文件的上传的工具类
*/
public final class DoUploadFile {
/**
* 依据传递参数上传文件
* @param formfile 上传的文件
* @param filePath 文件保存路径
* @throws IOException
*/
public static void saveFile(FormFile formfile,String filePath)
throws IOException {

String fileName = formfile.getFileName();

File dir = new File(filePath);
if(!dir.exists()) dir.mkdir();

// 获取上传文件的输入流
InputStream in = new BufferedInputStream(formfile.getInputStream());

// 实例化文件空壳(根据 filePath 路径名字符串和 fileName 路径名字符串创建一个新 File 实例)
File fileSaved = new File(filePath, fileName);

// 创建二进制文件输出流
OutputStream os = new FileOutputStream(fileSaved);

int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();

// 关闭文件流
os.close();
in.close();
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值