文件操作(转载)
原文地址:http://kinglaw05.blog.163.com/blog/static/59683314200893033226638/
一、File类
File类的对象主要用来获取文件本身的一些信息。例如文件所在的目录、文件的长度、文件读写权限等,不涉及对文件夹的读写操作。创建一个File对象的构造方法有3个:
■File(String filename);
■File(String directoryPath,String filename);
■File(File f,String filename);
其
中,filename是文件名,directoryPath是文件的路径,f是指定成一个目录的文件。使用File(String
filename)创建文件时,该文件被认为是与当前应用程序在同一目录中。由于JSP引擎是在bin下启动执行的。所以该文件被认为在bin目录中。
获取文件的属性
使用File类的下列方法获取文件本身的一些信息:
■public String getName() 获取文件的名字
■public boolean canRead() 判断文件是否是可读的
■public boolean canWrite() 判断文件是否是可被写的
■public boolean exits() 判断文件是否存在
■public long length() 获取文件的长度(单位是字节)
■public String getAbsolutePath() 获取文件的绝对路径
■public String getParent() 获取文件的父目录
■public boolean isFile() 判断文件是否是一个正常文件,而不是目录
■public boolean isDirectory() 判断文件是否是一个目录
■public boolean isHidden() 判断文件是否是隐藏文件
■public long lastModified() 获取文件最后修改的时间
创建目录
File对象调用方法public boolean mkdir()创建一个目录,如果创建成功就返回true,否则返回false(如果该目录已经存在将返回false)。
列出目录中的文件
如果File对象是一个目录,那么该对象可以调用下述方法列出该目录下的文件和子目录:
■public String[] list() 用字符串形式返回目录下的全部文件
■public String[] listFiles() 用File对象形式返回目录下的全部文件
列出指定类型的文件
我们有时需要列出目录下指定类型的文件。可以使用File对象的下述两个方法,列出指定类型的文件。
■public String[] list(FilenameFilter obj) 该方法用字符串形式返回目录下的指定类型的所有文件
■public File[] listFiles(FilenameFilter obj) 该方法用File对象返回目录下的指定类型的所有文件
FilenameFilter是一个接口,该接口有一个方法:
public boolean accept(File dir,String name);
当向list方法传递一个实现该接口的对象时,list方法将在列出文件时,让该文件调用accept方法检查该文件是否符合accept方法指定的目录和文件名字的要求。
删除文件和目录
File对象调用方法 public boolean delete() 可以删除当前对象代表的文件或目录。如果File对象表示的是一个目录,则该目录必须是一个空目录,删除成功将返回true。
二、使用字节流读写文件
JAVA的I/O流提供一条通道程序,可以使用这条通道把源中的数据送给目的地。输入流的指向称做源,程序从指向源的输入流中读取源中的数据。输出流的指向是数据要去的一个目的地,程序通过向输出流中写入数据把信息传递到目的地。如图:
java.io包提供大量的流类。所有字节输入流类都是InputStream(输入流)抽象类的子类,而所有字节输出流类都是OutputStream(输出流)抽象类的子类。
InputStream类的常用方法:
■int read() 输入流调用该方法从源中读取单个字节的数据,该方法返回字节值(0~255之间
的一个整数)。如果未读了字节就返回 -1。
■int read(byte b[]) 输入流调用该方法从源中试图读取b,length个字节到b中,返回实际读取的字节
数目。如果到达文件末尾则返回 -1。
■int read(byte b[],int off,int len) 输入流调用该方法从源中试图读取len个字节到b中,并返回实际读取的字节数
目。如果到达文件的末尾,则返回 -1。参数off指定从字节数组某个位置开始存
放读取的数据。
■void close() 输入流调用该方法关闭输入流。
■long skip(long numBytes) 输入流调用该方法跳过numBytes个字节,并返回实际跳过的字节数目。
OutputStream类的常用方法:
■void write(int n) 输出流调用该方法向输出流写入单个字节。
■void write(byte b[]) 输出流调用该方法向输出流写入一个字节数组。
■void write(byte b[],int off,int len) 从给定字节数组中起始于偏移量off处取len个字节写到输出流。
■void close() 关闭输出流。
FileInputStream类
FileInputStream类是从InputStream类中派生出来的简单输入类。该类的所有方法都是从InputStream类继承来的。它有两个构造方法:
■FileInputStream(String name)
■FileInputStream(File file)
第一个构造方法使用给定的文件名name创建一个FileInputStream对象。第二个构造方法使用File对象创建FileInputStream对象。参数name和file指定的文件称做输入流的源。输入流通过调用read方法读出源中的数据。
例如,为了读取一个名为abc.dat的文件,建立一个文件输入流对象,如下所示:
FileInputStream istream = new FileInputStream("abc.dat");
文件输入流构造方法的另一种格式是允许使用文件对象来指定要打开哪个文件。如下所示:
File f = new File("abc.dat");
FileInputStream istream = new FileInputStream(f);
FileOutputStream类
FileOutputStream类提供了基本的文件写入能力。构造方法有:
■FileOutputStream(String name)
■FileOutputStream(File file)
第
一个构造方法使用给定的文件名name创建一个FileOutputStream对象。第二个构造方法使用File对象创建
FileOutputStream对象。参数name和file指定的文件称做输出流的目的地,通过向输出流写入数据把信息传递到目的地。创建输出流对象
可能发生IOException异常,必须在try,catch语句块中创建输出流对象。
BufferedInputStream类和BufferedOutputStream类
为
了提高读写的效率,FileInputStream流经常和BufferedInputStream流配合使用,FileOutputStream流经常
和BufferedOutputStream流配合使用。BufferedInputStream类的一个常用的构造方法是:
BufferedInputStream(InputStream in)
该构造方法创建缓存输入流,该输入流的指向是一个输入流,当我们要读取一个文件,如abc.txt时,可以先建立一个指向该文件的文件输入流:
FileInputStream in = new FileInputStream("abc.txt");
然后再创建一个指向文件输入流in的输入缓存流(就好像把两个输入水管接在一起):
BufferedInputStream buffer = new BufferedInputStream(in);
这时,我们就可以让buffer调用read方法读取文件的内容。buffer在读取文件的过程中会进行缓存处理,提高读取的效率。同时,当要向一个文件,如def.txt,写入字节时,可以先建立一个指向该文件的文件输出流:
FileOutputStream out = new FileOutputStream("def.txt");
然后再创建一个指向输出流out的输出缓存流:
BufferedOutputStream buffer = new BufferedOutputStream(out);
这时,buffer调用write方法向文件写入内容时会进行缓存处理,提高写入的效率。需要注意的是,写入完毕后,须调用flush方法将缓存中的数据存入文件。
三、使用字符流读写文件
字节流不能直接操作
Unicode字符,所以JAVA提供了字符流。由于汉字在文件中占用2个字节,如果使用字节流,读取不当会出现乱码现象。采用字符流可以避免这个现象。
在Unicode字符中,一个汉字被看作一个字符。所有字符输入流类都是Reader抽象类的子类,所有字符输出流类都是Writer抽象类的子类。
Reader类中的常用方法:
■int read() 调用该方法从源中读取一个字符,该方法返回一个整数(0~65535之间的一个
整数,Unicode字符值),如果未读出字符就返回-1
■int read(char b[]) 调用该方法从源中读取b。length个字符到字符数组b,返回实际读取的字符数
目。如果到达文件的末尾,则返回-1
■int read(char b[],in off,int len) 调用该方法从源中读取len个字符并存放到字符数组b中,返回实际读取的字符
数目。如果到达文件的末尾,则返回-1。其中off参数指定read方法从字符数组
b中的什么地方存放数据。
■void close() 关闭输入流
■long skip(long numBytes) 调用该方法跳过numBytes个字符,并返回实际跳过的字符数目
Writer类中的常用方法:
■void write(int n) 向输出流写入一个字符
■void write(byte b[]) 向输入流写入一个字符数组
■void write(byte b[],int off,int length) 从给定数组中起始于偏移量off处取len个字符写到输出流
■void close() 关闭输出流
FileReader类
FileReader类是从Reader类中派生出来的简单输入类。该类的所有方法都是从Reader类继承来的。构造方法如下:
FileReader(String name)
FileReader(File file)
第一个构造方法使用给定的文件名name创建一个FileReader对象。第二个构造方法使用File对象创建FileReader对象。参数name和file指定的文件称做输入流的源。输入流通过调用read方法读出源中的数据。
FileWriter类
FileWriter类的构造方法:
FileWriter(String name)
FileWriter(File file)
第
一个构造方法使用给定的文件名name创建一个FileWriter对象。第二个构造方法使用File对象创建FileWriter对象。参数name和
file指定的文件称做输出流的目的地,通过向输出流中写入数据把信息传递到目的地。创建输入、输出流对旬会发生IOException异常,必须在
try,catch语句块中创建输入、输出流对象。
BufferedReader类和BufferedWriter类
为
了提高读写的效率,FileReader流经常和BufferedReader流配合使用,FileWriter流经常和BufferedWriter流
配合使用。BufferedReader流还可以使用方法String
readLine()读取一行,BufferedWriter流还可以使用方法void write(String s,int off,int
length)将字符串s的一部分写入文件,使用方法newLine()向文件写入一个行分隔符。
四、回压字符流
PushbackReader类创建的对
象称为回夺字符流。回压流可以使用unread(char
ch)将一个字符回压到该流中,被回压的字符是该回压流紧接着再调用read()方法时最先读出的字符。回压流可以用来监视读出的信息,当读出一个不需要
的信息时,可以不处理该信息,而将需要的信息回压,然后再读出回压的信息。该类的构造方法是:
PushbachReader(Reader in);
当
我们使用前面讲的字节输入流或字符输入流把JSP文件或超文本文件发送给客户时,客户的浏览器将解释运行超文本标记,客户无法看见原始的超文本文件或
JSP文件。我们可以使用回压流技术读取原始的网页文件。当读取到"<"符号时,将"<"回压,读取到">"符号时,
将">"回压。可能有人会问,为什么"<"要回压"<",而">"要回压">",这是因为在html代
码里,&TL代表<,而>代表>,具体可以看下表
五、数据流
DataInputStream类和DataOutputStream类创建的对象分别被称为数据输入流和数据输出流。它们允许程序按着与机器无关的风格读取JAVA原始数据。也就是说,当我们读取一个数值时,不必再关心这个数值应当是多少个字节。它们的构造方法为:
DataInputStream(InputStream in) 将创建的数据输入流指向一个由参数in指定的输入流,以便从后者读取数据
(按着与机器无关的风格读取。)
DataOutputStream(OutputStream out) 将创建的数据输出流指向一个由参数out指定的输出流,然后通过这个数
据输出流把JAVA数据类型的数据写到输出流out。
DataInputStream类和DataOutputStream类的部分方法
方法 |
描述 |
方法 |
描述 |
close() |
关闭流 |
readUTF() |
读取一个 UTF 字符串 |
readBoolean() |
读取一个布尔值 |
skipBytes(int n) |
跳过给定数量的字节 |
readByte() |
读取一个字节 |
writeBoolean(Boolean v) |
把一个布尔值作为单字节写入 |
readChar() |
读取一个字符 |
writeBytes(String s) |
写入一个字符串 |
readDouble() |
读取一个双精度浮点值 |
writeChars(String s) |
写入字符串 |
readFloat() |
读取一个单精度浮点值 |
writeDouble(double v) |
写入一个双精度浮点值 |
readInt() |
从文件中读取一个 int 值 |
writeFloat(float v) |
写入一个单精度浮点值 |
readlong() |
读取一个长型值 |
writeInt(int v) |
写入一个 int 值 |
readShort() |
读取一个短型值 |
writeLong(long v) |
写入一个长型值 |
ReadUnsignedByte() |
读取一个无符号字节 |
writeShort(int v) |
写入一个短型值 |
ReadUnsignedShort() |
读取一个无符号短型值 |
writeUTF(String s) |
写入一个 UTF 字符串 |
六、对象流
ObjectInputStream类和
ObjectOutputStream类分别是InputStream类和OutpuStream类的子类。ObjectInputStream类和
ObjectOutputStream类创建的对象分别称为对象输入流和对象输出流。对象输出流使用writeObject(Object
obj)方法将一个对象obj写入到一个文件,对象输入流使用readObject()方法读取一个对象到程序中。二者的构造方法为:
ObjectInputStream(InputStream in);
ObjectOutputStream(OutputStream out);
小插曲:要存储数据,可以使用散列表这种数据结构。要创建散列表对象,可以使用java.util包中的Hashtable类,该类的常用方法有:
■public Hashtable() 创建具有默认容量和装载因子为0.75的散列表。
■public Hashtable(int itialCapacity) 创建具有指定容量和装载因子为0.75的散列表。
■public Hashtable(int initialCapacity,float loadFactor) 创建具有默认容量和指定装载因子的散列。
■public void clear() 清空散列表。
■public boolean contains(Object o) 判断散列是否含有元素o。
■public Object get(Object key) 获取散列中具有关键字key的数据项。
■public boolean isEmpty() 判断散列表是否为空。
■public Object put(Object key,Object value) 向散列表添加数据项value并把关键字key关联到value。
■public Object remove(Object key) 删除关键字是key的数据项。
■public int size() 获取散列表中关键字的数目。
■public boolean containsKey(Object key) 判断散列是否使用了关键字key。
使用上述的get方法可以从散列表中检索某个数据。我们还可以借助Enumeration对象实现遍历散列表。一个散列表可以使用elements()方法获取一个Enumeration对象,后者使用nextElement()方法遍历散列表。
七、RandomAccessFile类
RandomAccessFile
类创建的流与之前的输入、输出流不同。RandomAccessFile类既不是输入流类InputStream类的子类,也不是输出流类
OutputStream类的子类。RandomAccessFile流的指向既可以作为源也可以作为目的地。换句话说,当我们想对一个文件进行读写操作
时,我们可以创建一个指向该文件的RandomAccessFile流,这样既可以从这个流中读取这个文件的数据,也可以通过这个流给这个文件写入数据。
它有两个构造方法:
■RandomAccessFile(String name,String mode)
■RandomAccessFile(File file,String mode)
参数name用来确定一个文件名,参数file是一个File对象,二者均是给出创建的流的源(也就是流的目的地)。参数mode取"r"(只读)或"rw"(可读写),决定创建的流对文件的访问权利。创建对象时应捕获IOException异常。
RandomAccessFile类的一些方法如下:
方法 |
描述 |
方法 |
描述 |
close() |
关闭文件 |
seek() |
定位文件指针在文件中的位置 |
getFilePointer() |
获取文件指针的位置 |
setLength(long newlength) |
设置文件的长度 |
length() |
获取文件的长度 |
skipBytes(int n) |
在文件中跳过给定数量的字节 |
read() |
从文件中读取一个字节的数据 |
write(byte b[]) |
写 b.length 个字节到文件 |
readBoolean() |
从文件中读取一个布尔值 |
writeBoolean(Boolean v) |
把一个布尔值作为单字节值写入文件 |
readByte() |
从文件中读取一个字节 |
writeByte(int v) |
向文件写入一个字节 |
readChar() |
从文件中读取一个字符( 2 个字节) |
writeBytes(String s) |
向文件写入一个字符串 |
readDouble() |
从文件中读取一个双精度浮点值( 8 个字节) |
writeChar(char c) |
向文件写入一个字符 |
readFloat() |
从文件中读取一个单精度浮点值( 4 个字节) |
writeChars(String s) |
向文件写入一个作为字符数据的字符串 |
readFully(byte b[]) |
读 b.length 字节放入数组 b ,完全填满该数组 |
writeDouble(double v) |
向文件写入一个双精度浮点值 |
readInt() |
从文件中读取一个 int 值( 4 个字节) |
writeFloat(float v) |
向文件写入一个单精度浮点值 |
readLine() |
从文件中读取一个文本行 |
writeInt(int v) |
向文件写入一个 int 值 |
readlong() |
从文件中读取一个长型值( 8 个字节) |
writeLong(long v) |
向文件写入一个长型 int 值 |
readShort() |
从文件中读取一个短型值( 2 个字节) |
writeShort(int v) |
向文件写入一个短型 int 值 |
readUTF() |
从文件中读取一个 UTF 字符串 |
writeUTF(String s) |
写入一个 UTF 字符串 |
八、文件上传
客户通过JSP页面上传文件给服务器时,该JSP页面必须含有File类型的表单,并且表单必须净ENCTYPE的属性值设成multipart/form-data。File类型表单如下所示:
<form action="接受上传文件的页面" method=post ENCTYPE="multipart/form-data">
<input type="File" name="名字">
</form>
JSP引擎可以让内置对象request调用方法getInputStream()获得一个输入流,通过这个输入流读入客户上传的全部信息,包括文件的内容以及表单域的信息。
根据HTTP协议,文件表单提交的信息中,前4行和后面的5行是表单本身的信息,中间部分才是客户提交的文件的内容。以下说明如何去掉表单的信息:
首
先,我们将客户提交的全部信息保存为一个临时文件,该文件的名字是客户的session对象的ID,不同客户的这个ID是不同的。然后读取该文件的第2
行,这一行中含有客户上传的文件的名字,获取这个名字。再获取第4行结束的位置,以及倒数第6行结束的位置,因为这两个位置之间的内容是上传文件的内容。
然后将这部分内容存入文件,该文件的名字和客户上传的文件名字保持一致。最后删除临时文件。
九、文件下载
JSP
内置对象response调用方法getOutputStream()可以获取一个指向客户的输出流,服务器将文件写入这个流,客户就可以下载这个文件
了。当JSP页面提供下载功能时,应当使用response对象向客户发送HTTP头信息,说明文件的MIME类型,这样,客户的浏览器就会调用相应的外
部程序打开下载的文件。例如,MS
word文件的MIME类型是application/msword,pdf文件的MIME类型是application/pdf。
十、分页读取文件
当读取一个较大的文件时,比如想让客户阅读一部小说,我们希望分页地读取该文件。可以借助session对象实现分页读取文件。当客户向JSP页面发出请求时,JSP页面建立一个指向该文件的输入流,通过输入流每次读取文件的若干行。
HTTP
协议是一种无状态协议。一个客户向服务器发出请求(request),然后服务器返回响应(response),连接就被关闭了。由于在服务器端不保留连
接的有关信息,因此当下一次连接时,服务器已没有以前的连接信息了,无法判断这一次连接和以前的连接是否属于同一客户。也就是说,如果我们请求每次读取
10行,那么第1次请求会读取文件的前10行,当我们第2次请求时,JSP页面会重新将输入流指向文件,这样我们第2次读取的内容和第1次读取的内容完全
相同,仍是文件的前10行。因此,必须使用会话来记录有关连接的信息。当客户选择从文件头开始读取文件时,创建指向文件的输入流连接,然后将这个输入流保
存到客户的会话中。当客户请求读取后10行时,直接使用客户会话中的输入流继续读取文件的后续10行就可以了。为了能够读取JSP文件,我们还需对读出的
文本进行回压流处理。
上一篇: JQuery禁止select下拉框选择
下一篇: Binary IO