Java的文件输入输出

时间:2023-02-26 17:06:47

第一节 文件读写器基本问题

文件操作、读写器的结构总图

第二节 文件读写各种类的研究

有关文件名及目录名的类、文件操作的一般方法、

FileInputStream/FileOutputStream、PipedInputStream/PipedOutputStream、

随机文件读写、字符流Reader/Writer、DataInput/DataOutput接口、

DataInputStream 和DataOutputStream过滤流、标准输入输出流

第三节 文件读写的应用实例

文本文件的读写、流文件读写、读写任意大文件应用、读写不同数据的应用、

读入多个文件信息的应用、不同的文件类读入和写出信息的应用

第一节 文件读写器基本问题

一、文件操作

文件分为两种,一种是文本文件,文本文件的内容以16 bit表示(2 byte),另一种为非文本文件(流文件),以8 bit表示(1 byte),比如图片、声音文件等等。这两种文件读写的一个很大的区别在于,文本文件读写单位是字符,它是两个字节一组的组合,是可以解析成字符的,而流文件每个读写单位为一个子节,单独的一个字节是没有办法解析成字符的,所以处理上有很大的不同。

二、读写器的结构总图

文件读写器所有的类都在类包 java.io 中,文件读入器一般使用字符input或者reader,文件写出器一般使用out或者writer。

流:它是通过缓冲机制将数据从生产者(如键盘、磁盘文件、内存或其他设备)传送到接受该数据的消费者(如屏幕、文件或者内存等)的这一过程的抽象。

文本文件读入器:Reader。

文本文件写出器:Write。

流文件读入器:InputStream。

流文件写出器:OutputStream。

而文件类File主要是用于创建文件对象,这是一个有关文件名及目录名的类:File 类独立于系统平台,利用构造函数

File( String path)、

File(String path, String FileName)、

File(File dir, String name) 等可以创建出File 对象,再利用canRead() 、canWrite()、 getParent()、 getPath()等成员函数实现对文件的各个属性的操作,以实现文件与目录的管理功能。

要点:File 类提供了一种与机器无关的方式来描述一个文件对象的属性,通过类File所提供的方法,可以得到文件或目录的描述信息,这主要包括名称、所在路经、可读性、可写性、文件的长度等,还可以生成新的目录、改变文件名、删除文件、列出一个目录中所有的文件等文件与目录的管理功能。

PipedReader

FileWriter

DataOutputStream

java.lang.Object

InputStream ect

OutputStream ect

FileInputStream ect

RandomAccessFile ect

PipedInputStream ect

FilterInputStream ect

DataInputStream ect

BufferedInputStream ect

FilterOutputStream ect

PipedOutputStream ect

FileOutputStream ect

BufferedOutputStream

File

Reader

InputStreamReader ect

BufferedReader ect

Writer

OutputStreamWriter er ect

BufferedWriter ect

FileReader

PipedWriter

第二节 文件读写各种类的研究

一、有关文件名及目录名的类

File 类独立于系统平台,利用构造函数

File( String path)、

File(String path, String FileName)、

File(File dir, String name) 等创建出File 对象;再利用canRead() 、canWrite()、 getParent()、 getPath()等成员函数实现对文件的各个属性的操作,以实现文件与目录的管理功能。

要点:

File 类提供了一种与机器无关的方式来描述一个文件对象的属性,通过类File所提供的方法,可以得到文件或目录的描述信息,这主要包括名称、所在路经、可读性、可写性、文件的长度等,还可以生成新的目录、改变文件名、删除文件、列出一个目录中所有的文件等文件与目录的管理功能。

实例:文件对象的属性操作方法

import java.io.*;

public class FileTest

{       public static void main(String []args)

{

                     String FileName=”C:\\temp\\myfile.dat”

                     File myFile=new File(FileName);

                     If( ! myFile. exists() )

                     {     System.err.println(“Can’t Find ” + FileName);

                    return;

              }

                     System.out.println(“File ” + FileName + “is ” +myFile.length() + “bytes Long !”);

              If( myFile. isDirectory() )

                     {     System.err.println(“File” + FileName +”Is a Directory !”);

                           return;

                     }

}

}

实例:演示File类中各种方法的使用

import java.io.*;

public class FileTest

{ //在执行该文件之前应该先拷贝一个文件名为File.txt的文件到当前程序所在的路径下

public static void main(String args[])

       {

      // “;”各个文件路径之间的分隔符

System.out.println("Path separator" +File.pathSeparator);     

System.out.println("Path separator char" +File.pathSeparatorChar);

System.out.println("separator " +File.separator);                    // “\”文件与路径之间的分隔符

System.out.println("separator char" +File.separatorChar);

File f=new File("File.txt");

System.out.println(f);

System.out.println("Exist ?" + f.exists());

System.out.println("name " + f.getName());

System.out.println("path " + f.getPath());

System.out.println("absolute path " + f.getAbsolutePath());

System.out.println("Parent " + f.getParent());

System.out.println("is a file ? " + f.isFile());

System.out.println("is a Directory ? " + f.isDirectory());   

System.out.println("length" + f.length());   

System.out.println("can read " + f.canRead());  

System.out.println("can write " + f.canWrite()); 

System.out.println("last modified" + f.lastModified());

File newF=new File("newFile");

System.out.println("...Rename " + f+"....");

f.renameTo(newF);     

System.out.println("name " + newF.getName());

System.out.println(f+"exist ? " + f.exists());      

System.out.println("... delete "+newF+"...");

newF.delete();

System.out.println(newF+ "exist ?" + newF.exists());

   }

}

实例:通过File类来实现列出一个目录下所有的*.class文件

import java.io.*;

public class FileFilterTest

{    public static void main(String args[])

              {

                     File dir =new File("E:/jdk1.2/bin");

                     Filter filter =new Filter("class");

                     System.out.println("list html files in directory" + dir);

                     String files[]=dir.list(filter);   //获得该目录下的各个文件名

                     for(int i=0; i<files.length; i++) //列出目录下所有匹配文件并存储到String 数组中。

              {     File f=new File(files[i]);

                            if(f.isFile())

                            System.out.println("file " +f);

                     else

                            System.out.println("sub directory " + f);    

              }

       }

}

class Filter implements FilenameFilter

{     String extent;

       Filter(String extent)

       {     this.extent=extent;

       }

       public boolean accept(File dir, String name)

       {     return name.endsWith("." + extent);

       }

}

二、文件操作的一般方法

1)输入输出抽象基类InputStream/OutputStream

实现文件内容操作的基本功能函数read()、 write()、close()等;一般都是创建出其派生类对象(完成指定的特殊功能)来实现文件读写。在文件读写的编程过程中主要应该注意异常处理的技术。

2)文件操作的一般方法:

(1)生成一个输入输出文件类的对象(根据所要操作的类型);

(2)调用此类的成员函数实现文件数据内容的读写;

(3)关闭此文件。

3)文件操作的一般要点:

在Java I/O编程中主要应该注意:

(1)异常的捕获---由于包java.io中几乎所有的类都声明有I/O异常,因此程序应该对这些异常加以处理。

(2)流结束的判断---方法read()的返回值为-1时;readLine()的返回值为null时。

三、字符流Reader/Writer:

Reader/Writer称之为字符流,提供的对字符流处理的类。由于文本文件属于字符信息,使用这种流处理问题比较不容易出现乱码。

注意,它们为抽象类,它的一个子类:

1)InputStreamReader(InputStream in) / OutputStreamWriter(OutputStream out):

它们可以使用指定的编码规范并基于字节流生成对应的字符流。

FileInputStream is=new FileInputStream("test.txt");

InputStreamReader isr=new InputStreamReader(is," iso-8859-1");

注意:为能正确地读出异种机上的字符,可以采用 ISO 8859_1的编码规范,它是一种映射到ASCII码的编码方式,可以在不同的平台之间正确地转换字符。

实例:

import java.io.*;

public class FileStreamsDemo {

public static void main(String[] args) throws IOException {

    //获得两个文件类

FileInputStream infile=new FileInputStream("c:\\text2.txt");

InputStreamReader in=new InputStreamReader(infile,"GBK");

FileOutputStream outfile=new FileOutputStream("c:\\text3.txt");

OutputStreamWriter out=new OutputStreamWriter(outfile);

   int c;

   //如果到了文件尾,read()方法返回的数字是-1

   while ((c = in.read()) != -1) out.write(c);   //使用write()方法向文件写入信息

    in.close();     //关闭文件读入类

    out.close();    //关闭文件写出类

}

}

2)BufferedReader(InputStreamReader isr, int size) / BufferedWrite(OutputStreamWriter osr, int size):

为提高字符流的处理效率,可以采用缓冲机制流。JDK引入了BufferedReader和BufferedWriter类,用来对字符流作成批的处理。其中的方法readLine()读起一行字符,而newLine()则是写入一行字符。由于提供缓冲机制,把任意的输入流或输出流“捆绑”到缓冲流上将获得性能的提高。可以在创建缓冲流对象时设置缓冲区的大小。

实例:

读文本文件的内容

import java.io.*;

public class CharInput

{     public static void main(String args[]) throws FileNotFoundException, IOException

              {     String s;

                     FileInputStream is=new FileInputStream("CharInput.java");

                     InputStreamReader ir=new InputStreamReader(is);

                     BufferedReader in =new BufferedReader(ir);

                     while((s=in.readLine()) !=null)

                            System.out.println("Read:" +s);

       }

}

实例:

读键盘输入的数据值

import java.io.*;

public class NumberInput

{            public static void main(String args[]) throws IOException

              {     String s;

                     InputStreamReader ir=new InputStreamReader(System.in);

                     BufferedReader in=new BufferedReader(ir);

                     String Str=in.readLine();

              System.out.println("Input Value is:" + Str);

                     int X=Integer.parseInt(Str);

            X=X*2;

            System.out.println("Input Value Changed after doubled:" +X );

       }

}

注意:

在Java中处理命令行方式的键盘输入时,都把输入的内容当作字符串看待。但由于Java没有提供自动将输入串转换为不同的类型数据的方法,所以要从键盘接收输入数据,必须由程序自己来完成类型转换。

实例:按行处理文件

package demopack;

import java.io.*;

public class streamDemo

{

       public static void main (String[] args) throws IOException

       {

            

              BufferedReader bin=null;

        BufferedWriter bout=null;

            

              File inputFile = new File("c:\\text2.txt");

              FileReader in = new FileReader(inputFile);

            

              File outputFile = new File("c:\\text3.txt");

        FileWriter out = new FileWriter(outputFile);

              bin=new BufferedReader(in);

              bout=new BufferedWriter(out);

            

        String inputLine;

            

               while((inputLine=bin.readLine())!=null)             

               {

                  bout.write(inputLine+"\r\n");

                  bout.flush();

            }

          

            in.close();     //关闭文件读入类

         out.close();    //关闭文件写出类

       }

            

}

(3)FileReader和FileWriter类:

由于InputStreamReader和OutputStreamWriter字符流类在创建流类的对象时必须以一个字节流作为原始的数据流来打开文件。为了能够直接将一个具体的文件名的文件直接转换为字符流类的对象,在java.io包中还为程序员提供了InputStreamReader和OutputStreamWriter字符流类的两个子类FileReader和FileWriter。

FileReader fr=new FileReader(“c:\\doc\\Java.doc”); 或

FileWriter fw=new FileWriter (“c:\\doc\\Java.doc”);

实例:

向文本文件写入文本字符内容

import java.io.;

public class TextFileWrite

{

              public static void main(String args[])

              {

                     try

                     {     //向文件追加数据,因为第二个参数为true表示为追加数据

                            FileWriter fr=new FileWriter(“UserDataFile.txt”,true);

                            fr.write(“这是我这次新追加的数据 !\n”);   //写入一行字符串

                     fr.close();

              }

              catch(IOException e)

              {

              }

       }

}

也可以用File对象和文件名建立联系。

实例:文本文件的读写

    样例:读入文件C:\\text1.txt,再创建一个C:\\text2.txt,把内容写入。

import java.io.*;

public class FileStreamsDemo {

public static void main(String[] args) throws IOException {

    //获得两个文件类

    File inputFile = new File("c:\\text1.txt");

    File outputFile = new File("c:\\text2.txt");

    FileReader in = new FileReader(inputFile);    //创建文件读入类

    FileWriter out = new FileWriter(outputFile); //创建文件写出类

    int c;

    //如果到了文件尾,read()方法返回的数字是-1

    while ((c = in.read()) != -1) out.write(c);   //使用write()方法向文件写入信息

    in.close();     //关闭文件读入类

    out.close();    //关闭文件写出类

}

}

四、标准输入输出流:

1)标准输入流:

System.in是InputStream类的对象,当程序中需要从键盘读入数据时候,只需要调用System.in中的read()方法。

try

{    char ch=System.in.read(); //返回二进制数据(低8位为键盘的ASCII码)

}

catch(IOException e)

{

}

注意:

1:必须捕获System.in.read()所抛出的异常;

2:执行System.in.read()方法将从键盘缓冲区读入一个字节的数据,然而返回的16位的数据,其低位才是真正的输入数据,高位为0;

3:使用System.in.read()来实现键盘输入时,如果键盘缓冲区中没有数据时,系统将进入阻塞状态。所以可以利用它来实现程序的暂停,用户输入后再继续执行。

2)标准输出流:

System.out它是打印输出流PrintStream类的对象,它定义了向屏幕输出不同类型数据的方法println()与 print()。

System.out.println()它可以输出多种不同类型的数据(如:boolean,double,float,int,long类型的变量以及Object类的对象);当输出类型为对象时,它将自动调用对象的toString()方法,因此在对象所在的类中应该重写toString()方法以输出特定的文字。

public class MyClass

{ public String toString()

    {    return "MyClass String";

    }

public staic void main(String args[])

    {    MyClass obj=new MyClass();

         System.out.println(obj); //将输出“MyClass String”文字串

    }

}

3)标准输入输出的重定向:

改变标准输入输出的方向为其它形式如从文件中输入

方法:利用System类中的3个static 方法可以实现。setIn(InputStream in)、setOut(PrintStream out)、setErr(PrintStream out)