可以帮我把这个程序再详细注释一下么?我看不懂需要注释的语句我都用//标出来了。
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<%@ page import="javax.servlet.*"%>
<%@ page import="javax.servlet.http.*"%>
<html><head><title>upFile</title></head>
<body bgcolor="#ffffff">
<%
int MAX_SIZE = 102400 * 102400; //定义上载文件的最大字节
String rootPath; // 创建根路径的保存变量
DataInputStream in = null; //声明文件读入类
FileOutputStream fileOut = null; //
String remoteAddr = request.getRemoteAddr(); //取得客户端的网络地址
String serverName = request.getServerName(); //获得服务器的名字
String realPath = request.getRealPath("/");//取得互联网程序的绝对地址
realPath = realPath.substring(0,realPath.lastIndexOf("\\")); //
rootPath = realPath + "\\upload\\"; //创建文件的保存目录
out.println("上传文件保存目录为"+rootPath);
String contentType = request.getContentType(); //取得客户端上传的数据类型
try{
if(contentType.indexOf("multipart/form-data") >= 0){ //
in = new DataInputStream(request.getInputStream()); //读入上传的数据
int formDataLength = request.getContentLength();
if(formDataLength > MAX_SIZE){
out.println("<P>上传的文件字节数不可以超过" + MAX_SIZE + "</p>");
return;
}
byte dataBytes[] = new byte[formDataLength]; //保存上传文件的数据
int byteRead = 0; //
int totalBytesRead = 0; //
while(totalBytesRead < formDataLength){ //上传的数据保存在byte数组
byteRead = in.read(dataBytes,totalBytesRead,formDataLength); //
totalBytesRead += byteRead; //
} 展开
1.
FileOutputStream fileOut = null; // 一个变量,将来用在准备把上传的文件保存到磁盘上这个文件中。你的代码中没贴出来,我想文件上传的服务端当然是要保存这个文件到服务器的磁盘上了。
2.
realPath = realPath.substring(0,realPath.lastIndexOf("\\"));
// request.getRealPath("/") 得到了服务器上这个 web app 的根目录下,然后作者想在这个目录下创建一个 upload 子目录,它先去掉 webapp 目录名串中的"\" 然后再加上 "\upload\",不过很明显,我们不应该这样假设,因为服务器可能是 Linux 平台用 "/" 而不是 "\",我们用 "/" 在 Windows 上不会出错,但 "\" 在 Linux 上就不清楚了,可以做个实验来验证,总之我们不应该假设这些,比如我们用 File 来帮助我们最方便:
File path = new File(realPath);
File uploadPath = new File(path, "upload"); // 在 path 的目录下创建一个 upload 子目录。这时我们不需要知道它是 Windows 还是 Linux 上的分隔符了。
3.
if(contentType.indexOf("multipart/form-data") >= 0){
// 文件上传应该是用 multipart/form-data 这种编码方式,普通的 application/x-www-form-urlencoded 只适合普通的请求,multipart/form-data 这种编码格式是MIME 编码,能处理多个多媒体文件内容,一次上传多个文件都是可以的。
这是一个 GET 请求的日志,它的内容是纯文本明文,调试器可以直接观看内容,一般把这个浏览器功能用于调试 HTTP 头是否正确。
对于 multipart/form-data 编码方式来说,它是和处理多媒体内容一样的。它的格式将会是类似如下:
4.
byteRead = in.read(dataBytes,totalBytesRead,formDataLength);
文件 I/O 读取时一般都是这种返回读取到的字节数,只要期望的长度的数据没有读取完,就循环读取,直到总数到了。不过一般基于性能上考虑,我们不需要准备那么大的临时数组来把整个文件的内容保存在内存中,要是上传的文件有1个G,岂不是占用1G的内存,这不是合理的设计,一般是读取的同时直接写入到另一个 out 文件中,而不是拼在数组中,
String fileName = contentType.substring(contentType.indexOf("name=") + "name=".lenght()).replaceAll("\"", ""); // 从 Content-Type: image/jpeg; name="IMG_20130423_115104.jpg" 中取出文件名并且去掉引号。
FileOutputStream fileOut = new FileOutputSream(new File(uploadPath, fileName));
byte[] dataBytes = new byte[512];
while(totalBytesRead < formDataLength){ //上传的数据保存在byte数组
byteRead = in.read(dataBytes,0, dataBytes.length);
totalBytesRead += byteRead;
if (byteRead != -1) {
output.write(dataBytes, 0, byteRead); // 立即写出到文件中,不用保存在数组中。
}
);
output.flush();
output.close();