Java的文件輸入輸出

第一節 文件讀寫器基本問題

文件操作、讀寫器的結構總圖

第二節 文件讀寫各種類的研究

有關文件名及目錄名的類、文件


操作的一般方法、

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)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章