Download presentation
Presentation is loading. Please wait.
Published byHarjanti Susanto Modified 6年之前
1
第六讲 JSP中的文件操作(2) 教学目的 本讲继续讲述JSP中使用Java输入、输出流实现文件的读写操作 。 1 文件上传 2 文件下载 3 分页读取文件
2
第六讲 JSP中的文件操作(2) 这一讲继续介绍有关JSP中文件操作的内容。
3
6.1 文件上传 客户通过一个JSP页面,上传文件给服务器时,该JSP页面必须含有File类型的表单,并且表单必须将ENCTYPE的属性值设成“multipart/form-data”,File类型表单如下所示: <Form action= “接受上传文件的页面” method= “post” ENCTYPE=“ multipart/form-data” <Input Type= “File” name= “picture” > </Form>
4
JSP引擎可以让内置对象request调用方法getInputStream()获得一个输入流,通过这个输入流读入客户上传的全部信息,包括文件的内容以及表单域的信息。
下面的例子1中,客户通过Example6_1.jsp页面上传如下的文本文件A.txt。 A.txt: 你好,我们正在学习文件的上传,request调用getInpuStream()可以获得一个输入流,通过这个输入流可以读取客户上传的全部信息,包括表单的头信息以及上传文件的内容。以后将讨论如何去掉表单的信息,获取文件的内容。 在accept.jsp页面,内置对象request调用方法getInputStream()获得一个输入流in、用FileOutputStream创建一个输出流o。输入流in读取客户上传的信息,输出流o将读取的信息写入文件B.txt,该文件B.txt被存放于服务器的F:/2000中。B.txt的内容如图6.3所示。
5
图6.1 选择上传的文件 图6.2 接收上传 图6.3 收到的上传信息
6
文件B.txt的前4行(包括一个空行)以及倒数5行(包括一个空行)是表单域的内容,中间部分是上传文件A.txt的内容。
例子1(效果如图6.1、6.2、6.3所示) Example6_1.jsp: page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P>选择要上传的文件:<BR> <FORM action="accept.jsp" method="post" ENCTYPE="multipart/form-data"> <INPUT type=FILE name="boy" size="38"> <BR> <INPUT type="submit" name ="g" value="提交"> </BODY> </HTML>
7
accept.jsp: <%@ page contentType="text/html;charset=GB2312" %>
page import ="java.io.*" %> <HTML> <BODY> <%try{ InputStream in=request.getInputStream(); File f=new File("F:/2000","B.txt"); FileOutputStream o=new FileOutputStream(f); byte b[]=new byte[1000]; int n; while((n=in.read(b))!=-1) {o.write(b,0,n); } o.close(); in.close(); catch(IOException ee){} out.print("文件已上传"); %> </BODY> </HTML> accept.jsp:
8
通过上面的讨论我们知道,按着HTTP协议,文件表单提交的信息中,前4行和后面的5行是表单本身的信息,中间部分才是客户提交的文件的内容。在下面的例子中我们通过输入输出流技术获取文件的内容,即去掉表单的信息。 首先,我们将客户提交的全部信息保存为一个临时文件,该文件的名字是客户的session对象的Id,不同客户的这个Id是不同的。然后读取该文件的第2行,这一行中含有客户上传的文件的名字,获取这个名字。再获取第4行结束的位置,以及倒数第6行的结束位置,因为这两个位置之间的内容是上传文件的内容。然后将这部分内容存入文件,该文件的名字和客户上传的文件的名字保持一致。最后删除临时文件。
9
在下面的例子2中,客户上传一个图象文件,还可以连接到showImage
在下面的例子2中,客户上传一个图象文件,还可以连接到showImage.jsp页面查看这个上传图象的效果。我们可以允许客户将文件上传到服务器的任何一个目录,为了让客户能查看上传图象的效果,下面的例子2将上传文件保存到一个web服务目录D:/tomcat/jakarta-tomcat-4.0/webapps/examples中,假设服务器的IP是: 。 例子2(效果如图6.4、6.5、6.6所示)
10
图6.4 选择上传的图象文件 图6.6 显示上传的图象文件 图6.5 接收上传的图象文件
11
Example6_2.jsp: page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <% String str=response.encodeURL("acceptFile.jsp"); %> <P>选择要上传的文件:<BR> <FORM action="<%=str %>" method="post" ENCTYPE="multipart/form-data"> <INPUT type=FILE name="boy" size="45"> <BR> <INPUT type="submit" name ="g" value="提交"> </FORM> </BODY> </HTML>
12
acceptFile.jsp: page contentType="text/html;charset=GB2312" %> page import ="java.io.*" %> <HTML> <BODY> <%try{ //用客户的session的id建立一个临时文件: String tempFileName=(String)session.getId(); //建立临时文件f1: File f1=new File("D:/Tomcat/jakarta-tomcat-4.0/webapps/examples/",tempFileName); FileOutputStream o=new FileOutputStream(f1); //将客户上传的全部信息存入f1: InputStream in=request.getInputStream(); byte b[]=new byte[10000]; int n; while( (n=in.read(b))!=-1) {o.write(b,0,n); } o.close();in.close(); //读取临时文件f1,从中获取上传文件的名字,和上传的文件的内容:
13
RandomAccessFile random=new RandomAccessFile(f1,"r");
续前页: RandomAccessFile random=new RandomAccessFile(f1,"r"); //读出f1的第2行,析取出上传文件的名字: int second=1; String secondLine=null; while(second<=2) {secondLine=random.readLine(); second++; } //获取第2行中目录符号'\'最后出现的位置 int position=secondLine.lastIndexOf('\\'); //客户上传的文件的名字是: String fileName=secondLine.substring(position+1,secondLine.length()-1); random.seek(0); //再定位到文件f1的开头。 //获取第4行回车符号的位置:
14
long forthEndPosition=0;
续前页: long forthEndPosition=0; int forth=1; while((n=random.readByte())!=-1&&(forth<=4)) { if(n=='\n') { forthEndPosition=random.getFilePointer(); forth++; } //根据客户上传文件的名字,将该文件存入磁盘: File f2=new File("D:/Tomcat/jakarta-tomcat-4.0/webapps/examples/",fileName); session.setAttribute("Name",fileName);//供showImage.jsp页面使用。 RandomAccessFile random2=new RandomAccessFile(f2,"rw"); //确定出文件f1中包含客户上传的文件的内容的最后位置,即倒数第6行。
15
random.seek(random.length());
续前页: random.seek(random.length()); long endPosition=random.getFilePointer(); long mark=endPosition; int j=1; while((mark>=0)&&(j<=6)) { mark--; random.seek(mark); n=random.readByte(); if(n=='\n') { endPosition=random.getFilePointer(); j++; } //将random流指向文件f1的第4行结束的位置: random.seek(forthEndPosition); long startPoint=random.getFilePointer(); //从f1读出客户上传的文件存入f2(读取从第4行结束位置和倒数第6行之间的内容)。
16
while(startPoint<endPosition-1)
续前页: while(startPoint<endPosition-1) { n=random.readByte(); random2.write(n); startPoint=random.getFilePointer(); } random2.close();random.close(); f1.delete(); //删除临时文件 catch(IOException ee){} out.print("文件已上传"); %> <P> 查看上传的图象效果 <%String str=response.encodeURL("showImage.jsp"); <FORM action="<%=str%>"> <Input type=submit value="查看"> </FOrm > </BODY> </HTML>
17
showImage.jsp: <HTML> <BODY>
<% String name=(String)session.getAttribute("Name"); if(name==null) {name=""; } out.print("<image src= %> </BODY> </HTML>
18
6.2 文件下载 JSP内置对象response调用方法getOutputStream()可以获取一个指向客户的输出流,服务器将文件写入这个流,客户就可以下载这个文件了。 当JSP页面提供下载功能时,应当使用response对象向客户发送HTTP头信息,说明文件的MIME类型,这样客户的浏览器就会调用相应的外部程序打开下载的文件。例如,Ms-Word文件的MIME类型是application/msword,pdf文件的MIME类型是application/pdf。点击点击资源管理器→工具→文件夹选项→文件类型可以查看文件的相应的MIME类型。
19
在下面的例子3中,客户在Example6_3页面点击超链接下载一个zip文档。 例子3(效果如图6.7、6.8所示)
图6.8下载文件 图6.7 选择下载文件
20
Example6_3.jsp: loadFile.jsp:
page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P>点击超链接下载Zip文档book.Zip <BR> <A href="loadFile.jsp">下载book.zip </Body> </HTML> loadFile.jsp: page contentType="text/html;charset=GB2312" %> page import="java.io.*" %> <HTML> <BODY> <% //获得响应客户的输出流: OutputStream o=response.getOutputStream(); //输出文件用的字节数组,每次发送500个字节到输出流: byte b[]=new byte[500];
21
//下载的文件: 续前页: File fileLoad=new File("f:/2000","book.zip");
//客户使用保存文件的对话框: response.setHeader("Content-disposition","attachment;filename="+"book.zip"); //通知客户文件的MIME类型: response.setContentType("application/x-tar"); //通知客户文件的长度: long fileLength=fileLoad.length(); String length=String.valueOf(fileLength); response.setHeader("Content_Length",length); //读取文件book.zip,并发送给客户下载: FileInputStream in=new FileInputStream(fileLoad); int n=0; while((n=in.read(b))!=-1) { o.write(b,0,n); } %> </BODY> </HTML>
22
分页读取文件 当读取一个较大的文件时,比如想让客户阅读一部小说,我们希望分页地读取该文件。可以借助session对象实现分页读取文件。当客户向JSP页面发出请求时,JSP页面建立一个指向该文件的输入流,通过文件流每次读取文件的若干行。 我们已经知道HTTP协议是一种无状态协议。一个客户向服务器发出请求(request)然后服务器返回响应(respons),连接就被关闭了。在服务器端不保留连接的有关信息,因此当下一次连接时,服务器已没有以前的连接信息了,无法判断这一次连接和以前的连接是否属于同一客户。也就是说,如果我们请求每次读取10行,那么第一次请求会读取文件的前10行,当我们第2次请求时,JSP页面会重新将输入流指向文件,这样,我们第2次读取的内容和第一次读取的完全相同,仍是文件的前10行。因此,必须使用会话来记录有关连接的信息。当客户第一次请求该页面时,创建指向文件的输入流连接,然后将这个输入流保存到客户的会话中,当客户再次请求这个页面时,直接使用客户会话中的输入流继续读取的文件的后续10行就可以了。
23
例子4 readFileByLine.jsp:
page contentType="text/html;charset=GB2312" %> page import ="java.io.*" %> <% String s=request.getParameter("g"); //获取客户提交的信息(是否重新读取文件) if(s==null) {s=""; } byte b[]=s.getBytes("ISO "); s=new String(b); File f=null; FileReader in=null; BufferedReader buffer=null; long startTime=session.getCreationTime(); long endTime=session.getLastAccessedTime(); if(endTime-startTime==0) //当第一次请求该页面时,建立和文件的输入流连接。
24
{ f=new File("f:/2000","A.txt");
in=new FileReader(f); buffer=new BufferedReader(in); session.setAttribute("file",f); session.setAttribute("in",in); session.setAttribute("buffer",buffer); } if(s.equals("重新读取文件")) //当请求重新读取文件时,建立和文件的输入流连接。 //从session 对象中获取该用户的输入流对象: try{ String str=null; int i=1; f=(File)session.getAttribute("file"); in=(FileReader)session.getAttribute("in"); buffer=(BufferedReader)session.getAttribute("buffer"); 续前页:
25
while( ((str=buffer.readLine())!=null)&&(i<=5))
续前页: while( ((str=buffer.readLine())!=null)&&(i<=5)) { out.print("<BR>"+str); i++; } catch(IOException e) { out.print("文件不存在,或读取出现问题"); %> <%String code=response.encodeURL("readFileByLine.jsp "); <HTML> <BODY> <P><BR>点击按钮读取下5行: <FORM action="<%=code%>" method="post" name=form> <Input type=submit value="读取文件的下5行"> </FORM> <P><BR>点击按钮读重新读取文件: <FORM action="" method="post" name=form> <Input type=submit name="g" value="重新读取文件"> </BODY> </HTML>
Similar presentations