9.1 字节流和字符流
对java语言而言,输入/输出包括:对外设通道的输入/输出、对文件的读写、对网络数据的读和写。java语言采用流的机制实现输入和输出。流是一种有方向的字节/字符数据序列。
9.1.1 File对象
File对象对应一个目录或文件,只用来命名文件、查询文件属性和处理目录,不提供读写文件操作。
9.1.2 流对象
java程序的输入和输出流成为流对象,文件读写的主要操作包括:建立流对象、读数据、写数据和关闭流。输入输出流由文件名或File对象创建。
根据输入输出数据的类型是字节还是字符,java.io提供两种基本抽象类:一种用于读写字节,另一种用于读写字符。
字节流用于读写二进制数据,比如图像和声音文件等。字节流数据是8位的,由InputStream类和OutputStream类为字节流提供API和部分实现。字节流读和写操作由FileInputStream类和FileOutputStream类提供支持。它们分别是InputStream类和OutputStream类的子类。
字符流数据是16为的Unicode字符,字符流能处理Unicode字符集中的任何字符,由Reader类和Writer类为字符流提供API和部分实现。读和写操作由FileReader类和FileWriter类提供支持。它们分别是Reader类和Writer类的子类。
例如:一个文件复制的应用程序。
- import java.io.*;
- class Example{
- public static void main(String args[])
- File inputFile = new File("file1.txt");
- File outputFile = new File("file2.txt");
- int ch;
- try{
- FileReader in =new FileReader(inputFile);
- FileWriter out = new FileWriter(outputFile);
- System.out.println("文件复制程序开始工作:");
- while((ch=in.read())!=-1){
- out.write(ch);
- }
- in.close();
- out.close();
- System.out.println("文件复制程序工作结束");
- }catch(FileNotException e1){
- System.out.println("文件没有找到!");
- }catch(IOException e1){
- System.out.println("File read Error");
- }
- }
- 9.2缓冲式输入输出
当程序处理的文件按行组织,并且行不是定长时,用前面所述的流类实现很不方便。程序如果要按行输入输出,需采用缓冲式输入输出方式。
9.2.1 缓冲式输入
采用缓冲式输入时,对于程序的输入请求,系统一次性输入足够多的内容放在内存缓冲区中,供程序以后的输入请求使用,待缓冲区内容用完,再一次性输入做够多的数据。
程序要采用缓冲式输入,只要先创建FileReader对象,再利用FileReader对象创建BufferedReader对象,习惯成为将FileReader对象接到BufferedReader对象上。如:
file=new FileReader("abc.txt");
in = new BufferedReader(file);
这样,就可以对BufferedReader对象in使用readLine方法。
9.2.2 缓冲式输出
程序只要先创建FileWriter对象,再利用FileWriter对象创建BufferedWriter对象。如果想立即写入到文件,则需调用flush方法。
9.3 随即访问
流在某些应用中,不希望顺序读写流。例如,跳过部分不需要的数据,去读更后面的数据;或者,对早先读过的数据要重新读入等。这样的应用需要采用随机访问方式。
文件随机访问可利用RadomAccessFile类实现,由这个类创建的流既可以随机输出,也可以随机输入。
例如,下面的程序把若干long型整数写到一个名为longData。dat文件中,然后按相反顺序读出这些写入的整数。
- import java.io.*;
- public class Example{
- public static void main(String args[]){
- RadomAccessFile inOut=null;
- long data[]={151,278,235,206,-170,32,43,21,83,47};
- try{
- inOut=new RadomAccessFile("longData.dat","rw");
- for(int i=0;i<data.length;i++){
- inOut.writeLong(data[i]);
- }
- for(int i=data.length-1;i>=0;i--){
- inOut.seek(i*8);//long型数据占8个字节,第i个整数自i*8字节开始
- System.out.println(" "+inOut.readLong()+((i==0)?"/n":","));
- }
- inOut.close();
- }catch(FileNotFoundExceptino e1){
- System.out.println("file not found");
- }catch(IOException e2){
- System.out.println("file read/write error");
- }
- }
- }
可以使用javax.swing包中的类JFileChooser实现打开和保存文件对话框。
1、JFileChooser类的构造方法
(1)JFileChooser(),建立一个JFileChooser对象,默认的文件对话框路径是用户的Home目录。
(2)JFileChooser(String currentDircetoryPath),建立一个JFileChooser对象,并设置文件对话框的打开路径。
2、其他常用方法
(1)showOpenDialog(),打开文件对话框
(2)showSaveDialog(),保存文件对话框
3、设置筛选条件
使用FileFilter类,该类预设两个方法,accept(File f),getDescription()。当目录中的文件与筛选条件相符时,accept方法返回true,并将此文件名显示在对话框中。而getDescription方法则是对筛选条件的描述,由程序指定,例如“*.java”等。
由于FileFilter类是一个抽象类,需要继承这个类,编写一个实现类,实现上述两个方法。然后,就可以使用JFileChooser类的addChooseFileFilter方法,或者是SetFileFilter方法设置筛选条件。- class MyFileFilter extends FileFilter{
- string ext;
- MyFileFilter(String t){
- ext=t;
- }
- public boolean accept(File file){
- if(file.isDirectory()) return true;
- String fn=file.getName();
- int index=fn.lastIndexOf('.');
- if(index>0&&index<fn.length()-1){
- String extension=fn.substring(index+1).toLowerCase();
- if(extension.equals(ext)) return true;
- }
- return false;
- }
- public String getDescription(){
- if(ext.equals("java")){
- return "java Source File(*.java)";
- }
- if(ext.equals("txt")){
- return "Txt File(*.txt)";
- }
- }
- }