JSP
网页应用程序开发
网页应用程序开发
教学目的:了解JSP中对文件操作的实现方法
5.1 File类
java.io.File类用来获取文件/目录本身的信息,如所在目录、文件长度、读写权限等。
File类的构造方法:
- File(String filename) filename是文件名字或绝对路径(注意:如不加路径,则默认文件位于Tomcat安装目录下的bin目录中)
- File(String directoryPath, String filename) directoryPath是文件所在目录路径,filename是文件名字
- File(File f, String filename) f是目录对象,filename是文件名字
File类的常用方法:
- String getName() 获取文件名字
- String getAbsolutePath() 获取文件的绝对路径
- boolean exists() 判断文件是否存在
- long length() 获取文件的长度(以字节为单位)
- boolean isFile() 判断文件是否为真正的文件而非目录
- boolean isDirectory() 判断文件是否为目录
- boolean canRead() 判断文件是否可读
- boolean canWrite() 判断文件是否可写
列出文件——如果File对象为目录,则可调用listFiles方法列出该目录下的文件和子目录
- public File[] listFiles() 获取目录下的全部File对象
例:列出指定目录下的文件
<h3>在线文件柜</h3>
<%
String myfiles = application.getRealPath("/files/");
File dir = new File(myfiles);
File file[] = dir.listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
out.print(file[i].getName().toString() + " - " + file[i].length() + "字节<br />");
}
}
%>
创建文件——调用createNewFile方法创建文件,mkdir方法创建目录
- boolean createNewFile() 创建文件,成功则返回true,否则返回false
- boolean mkdir() 创建目录,成功则返回true,否则返回false
例:根据用户提交的名字新建文件
<%
String newname = request.getParameter("newname");
if (newname != null && newname != "" ) {
File newFile = new File(myfiles, newname);
newFile.createNewFile();
}
%>
删除文件——调用delete方法删除对象代表的文件或目录(目录必须为空才可删除)
- boolean delete() 删除文件或目录,成功则返回true,否则返回false
例:根据用户提交的名字删除文件或目录
<%
String delname = request.getParameter("delname");
if (delname != null && delname != "" ) {
File delFile = new File(myfiles, delname);
delFile.delete();
}
%>
5.2 使用字节流读写文件
Java使用输入输出流读取和写入数据,常用的输入输出流类是文件输入/输出流FileInputStream/FileOutputStream
FileInputStream/FileOutputStream以字节为单位顺序地读取/写入文件
FileInputStream类的构造方法:
- FileInputStream(File file) file是文件对象
FileInputStream类的常用方法:
- int read(byte[] b) 读取输入流并存入字节数组
- void close() 关闭输入流
FileOutputStream类的构造方法:
- FileOutputStream(File file) file是文件对象
FileOutputStream类的常用方法:
- void write(byte[] b) 将字节数组写入输出流
- void close() 关闭输出流
为了提高读写效率,FileInputStream/FileOutputStream需要与缓存输入/输出流BufferedInputStream/BufferedOutputStream配合使用
BufferedInputStream类的构造方法:
- BufferedInputStream(InputStream in) in是输入流对象
BufferedInputStream类的常用方法:
- int read(byte[] b) 读取缓存输入流并存入字节数组
- void close() 关闭缓存输入流
BufferedOutputStream类的构造方法:
- BufferedOutputStream(OutputStream out) out是输出流对象
BufferedOutputStream类的常用方法:
- void write(byte[] b) 将字节数组写入缓存输出流
- void flush() 刷新缓存即把缓存内容发送到文件输出流
- void close() 关闭缓存输出流
例:根据用户提交的名字,使用字节流读取文件内容并显示
<%
String filename = request.getParameter("filename");
if (filename != null && filename != "" ) {
File f = new File(myfiles, filename);
try {
FileInputStream i = new FileInputStream(f);
BufferedInputStream bi = new BufferedInputStream(i);
byte b[] = new byte[100];
int n = 0;
while ((n = bi.read(b)) != -1) {
String temp = new String(b, 0, n);
out.print(temp);
}
bi.close();
i.close();
}
catch(IOException e) {}
}
%>
例:根据用户提交的内容,使用字节流写入文件内容
<%
String content = request.getParameter("content");
if (content != null) {
File f = new File(myfiles, filename);
try {
FileOutputStream o = new FileOutputStream(f);
BufferedOutputStream bo = new BufferedOutputStream(o);
byte c[] = content.getBytes();
bo.write(c);
bo.flush();
bo.close();
o.close();
}
catch(IOException e) {}
}
%>
5.3 使用字符流读写文件
字符流类以Unicode字符为单位读写数据。在Unicode编码方式下,一个英文字母和一个汉字都是一个字符。常用的字符流类是输入/输出字符流InputStreamReader/InputStreamWriter及其子类文件字符流FileReader/FileWriter。
(注意:FileWriter/FileReader不支持通过参数指定字符编码方式,因此无法用于utf-8字符编码的文件)
为了提高读写效率,字符流需要与缓存读取/写入流BufferedReader/BufferedWriter配合使用。
例:使用字符流读取文件内容
<%
if (filename != null && filename != "" ) {
File f = new File(myfiles, filename);
StringBuffer mess = new StringBuffer();
try {
InputStreamReader r = new InputStreamReader(new FileInputStream(f), "utf-8");
BufferedReader br = new BufferedReader(r);
String temp;
while ((temp = br.readLine()) != null) {
mess.append(temp + "\n");
}
br.close();
r.close();
}
catch(IOException e) {}
out.print(new String(mess));
}
%>
例:使用字符流写入文件内容
<%
String content = request.getParameter("content");
if (content != null) {
byte b[] = content.getBytes("iso-8859-1");
content = new String(b, "utf-8");
File f = new File(myfiles, filename);
try {
OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
BufferedWriter bw = new BufferedWriter(w);
bw.write(content);
bw.close();
w.close();
}
catch(IOException e) {}
}
%>5.4 文件上传
上传文件需要使用包含文件域的表单(表单的编码类型应为multipart/form-data),让内置对象request调用getInputStream方法即可获得一个用户上传信息的输入流并输出到指定的文件。
例:上传文件并保存为指定的名字
<%
try {
InputStream i = request.getInputStream();
File upFile = new File(myfiles, "upFile.txt");
FileOutputStream o = new FileOutputStream(upFile);
byte b[] = new byte[1000];
int n;
while ((n = i.read(b)) != -1) {
o.write(b, 0, n);
}
o.close();
i.close();
out.print("文件上传成功!");
}
catch(IOException e) {
out.print("文件上传失败!");
}
%>
注意:以上程序保存的文件不仅包含原文件,还有用户提交的其他信息(文件的前4行和末5行内容),应该去除这些内容才能得到原文件。
例:上传文件程序修正版(本例使用更灵活的随机存取文件类RandomAccessFile进行文件读写,该类的seek方法可自由指定当前流的读写位置,getFilePointer方法可获取当前流的读写位置)
<%
try {
//建立临时文件,文件名为用户会话ID
String tempFile = (String)session.getId();
File f1 = new File(myfiles, tempFile);
FileOutputStream o = new FileOutputStream(f1);
//将用户上传的全部信息存入临时文件
InputStream i = request.getInputStream();
byte b[] = new byte[10000];
int n;
while ((n = i.read(b)) != -1) {
o.write(b, 0, n);
}
o.close();
i.close();
//读取临时文件
RandomAccessFile random = new RandomAccessFile(f1, "r");
//从第2行最后一个=字符之后获取原文件的名字
int second = 1;
String secondLine = null;
while (second <= 2) {
secondLine = random.readLine();
second++;
}
int position = secondLine.lastIndexOf('=');
String fileName = secondLine.substring(position + 2, secondLine.length() - 1);
//确定原文件的开始:从第4行的回车符起
long forthEndPosition = 0;
int forth = 1;
while((n = random.readByte()) != -1 && (forth <= 4)) {
if (n == '\n') {
forthEndPosition = random.getFilePointer();
forth++;
}
}
//保存原文件
byte cc[] = fileName.getBytes("iso-8859-1");
fileName = new String(cc, "utf-8");
File f2 = new File(myfiles, fileName);
RandomAccessFile random2 = new RandomAccessFile(f2, "rw");
//确定原文件的末尾:到倒数第6行止
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流指向原文件第4行结束的位置
random.seek(forthEndPosition);
long startPoint = random.getFilePointer();
//读取临时文件存入新文件
while (startPoint < endPosition - 1) {
n = random.readByte();
random2.write(n);
startPoint = random.getFilePointer();
}
random2.close();
random.close();
//删除临时文件
f1.delete();
out.print("文件上传成功!");
}
catch(IOException e) {
out.print("文件上传失败!");
}
%>
5.5 文件下载
使用response对象的setHerader方法即可向客户端发送下载文件的HTTP头信息。
response.setHeader("Content-disposition","attachment;filename=<下载文件名>");
例:根据用户提交的名字下载文件
String down = request.getParameter("down");
if (down != null && down != "" ) {
byte d[] = down.getBytes("iso-8859-1");
down = new String(d, "utf-8");
response.setHeader("Content-disposition","attachment;filename=" + down);
try {
File dl = new File(myfiles, down);
FileInputStream i = new FileInputStream(dl);
OutputStream o = response.getOutputStream();
int n = 0;
byte b[] = new byte[1000];
while((n = i.read(b)) != -1) {
o.write(b, 0, n);
}
o.close();
i.close();
}
catch(Exception e) {}
}
博主 in 教程 01:59下午 10月 13, 2012
Tags: 教学