国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

java學習筆記16--I/O流和文件

2019-11-14 23:33:11
字體:
來源:轉載
供稿:網友
java學習筆記16--I/O流和文件

本文地址:http://m.survivalescaperooms.com/archimedes/p/java-study-note16.html,轉載請注明源地址。

IO(Input Output)流

IO流用來處理設備之間的數據傳輸,對數據的操作是通過流的方式,Java用于操作流的對象都在IO包中

輸入/輸出流可以從以下幾個方面進行分類

從流的方向劃分:

輸入流、輸出流

從流的分工劃分:

節點流、處理流

從流的內容劃分:

面向字符的流、面向字節的流

字符流和字節流

字符流的由來: 因為數據編碼的不同,而有了對字符進行高效操作的流對象。本質其實就是基于字節流讀取時,去查了指定的碼表。 字節流和字符流的區別:

  • 讀寫單位不同:字節流以字節(8bit)為單位,字符流以字符為單位,根據碼表映射字符,一次可能讀多個字節。

  • 處理對象不同:字節流能處理所有類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。

結論:只要是處理純文本數據,就優先考慮使用字符流。 除此之外都使用字節流。

流按流向分為:輸入流、輸出流

IO流常用基類

字節流的抽象基類:

•InputStream,OutputStream。

字符流的抽象基類:

•Reader, Writer。

注:由這四個類派生出來的子類名稱都是以其父類名作為子類名的后綴。

如:InputStream的子類FileInputStream。

如:Reader的子類FileReader。

Java流操作有關的類或接口:

Java流類圖結構:

讀寫文本文件

寫文本文件

例:在C盤根目錄創建文本文件Hello.txt,并往里寫入若干行文本
import java.io.*;   class Ex1{  public static void main ( String[] args ) throws IOException {       //main方法中聲明拋出IO異常     String fileName = "C://Hello.txt";      FileWriter writer = new FileWriter( fileName );        writer.write( "Hello!/n");      writer.write( "This is my first text file,/n"  );       writer.write( "You can see how this is done./n" );      writer.write("輸入一行中文也可以/n");     writer.close();   }}

說明:

每次運行這個程序,都將刪除已經存在的”Hello.txt”文件,創建一個新的同名文件。FileWriter的構造方法有五個,本例是通過一個字符串指定文件名來創建。FileWriter類的write方法向文件中寫入字符

Writer類的流可實現內部格式到外部磁盤文件格式的轉換

“Hello.txt”是一個普通的ASCII碼文本文件,每個英文字符占一個字節,中文字符占兩個字節

Java程序中的字符串則是每個字符占兩個字節的,采用Unicode編碼

close方法清空流里的內容并關閉它。如果不調用該方法,可能系統還沒有完成所有數據的寫操作,程序就結束了

在看一個例子:處理IO異常

import java.io.*;   class Ex2 {  public static void main ( String[] args ) {    String fileName = "c://Hello.txt" ;    try {  //將所有IO操作放入try塊中         FileWriter writer = new FileWriter( fileName ,true );         writer.write( "Hello!/n");           writer.write( "This is my first text file,/n"  );           writer.write( "You can see how this is done. /n" );         writer.write("輸入一行中文也可以/n");         writer.close();    }    catch ( IOException iox) {          System.out.

說明:

運行此程序,會發現在原文件內容后面又追加了重復的內容,這就是將構造方法的第二個參數設為true的效果

如果將文件屬性改為只讀屬性,再運行本程序,就會出現IO錯誤,程序將轉入catch塊中,給出出錯信息

BufferedWriter類

如果需要寫入的內容很多,就應該使用更為高效的緩沖器流類BufferedWriter

FileWriter和BufferedWriter類都用于輸出字符流,包含的方法幾乎完全一樣,但BufferedWriter多提供了一個newLine()方法用于換行

使用BufferedWriter完成上面的功能:

import java.io.*; class Ex3 {    public static void main ( String[] args ) throws IOException    {        String fileName = "C:/newHello.txt" ;        BufferedWriter out = new BufferedWriter(                                   new  FileWriter( fileName ) );       out.write( "Hello!"  );             out.newLine() ;           out.write( "This is another text file using BufferedWriter,"  );           out.newLine(); ;        out.write( "So I can use a common way to start a newline" );         out.close();    }}

讀文本文件

FileReader類

從文本文件中讀取字符

繼承自Reader抽象類的子類InputStreamReader

BufferedReader

讀文本文件的緩沖器類

具有readLine()方法,可以對換行符進行鑒別,一行一行地讀取輸入流中的內容

繼承自Reader

文件輸入方法:

BufferedReader in = new BufferedReader(new FileReader( fileName) );

從Hello.txt中讀取文本并顯示在屏幕上

import java.io.*;class Ex4 {    public static void main ( String[] args ) {        String fileName = "C:/Hello.txt" , line;        try {             BufferedReader in = new BufferedReader(                                              new FileReader( fileName  ) );             line = in.readLine();   //讀取一行內容             while ( line != null ) {                 System.out.println( line );                line = in.readLine();             }             in.close();         }       catch ( IOException iox ) {              System.out.println("Problem reading " + fileName );          }    }}

運行該程序,屏幕上將逐行顯示出Hello.txt文件中的內容

FileReader對象:創建后將打開文件,如果文件不存在,會拋出一個IOException

BufferedReader類的readLine()方法:從一個面向字符的輸入流中讀取一行文本。如果其中不再有數據,返回null

Reader類的read()方法:也可用來判別文件結束。該方法返回的一個表示某個字符的int型整數,如果讀到文件末尾,返回 -1。據此,可修改本例中的讀文件部分:

int c;while((c=in.read())!= -1)  System.out.print((char)c);

close()方法:為了操作系統可以更為有效地利用有限的資源,應該在讀取完畢后,調用該方法

指定源文件和目標文件名,將源文件的內容拷貝至目標文件。調用方式為:

java copy sourceFile destinationFile

class CopyMaker {    String sourceName, destName;    BufferedReader source;    BufferedWriter dest;    String line;    private boolean openFiles() {        try {            source = new BufferedReader(new FileReader(sourceName));        } catch (IOException ex) {            System.out.println("Problem opening " + sourceName);            return false;        }        try {            dest = new BufferedWriter(new FileWriter(destName));        } catch (IOException ex) {            System.out.println("Problem opening " + destName);            return false;        }        return true;    }    private boolean copyFiles() {        try {            line = source.readLine();            while(line != null) {                dest.write(line);                dest.newLine();                line = source.readLine();            }        } catch (IOException ex) {            System.out.println("Problem reading or writing");            return false;        }        return true;    }    private boolean closeFiles() {        boolean retVal = true;        try {            source.close();        } catch (IOException ex) {            System.out.println("Prolem closing " + sourceName);            retVal = false;        }        try {            dest.close();        } catch (IOException ex) {            System.out.println("Problem closing " + destName);            retVal = false;        }        return retVal;    }    public boolean copy(String src, String dst) {        sourceName= src;        destName = dst;        return openFiles() && copyFiles() && closeFiles();    }}public class CopyFile {    public static void main(String[] args) {        if(args.length == 2)            new CopyMaker().copy(args[0], args[1]);        else            System.out.println("Please Enter names");    }}
讀寫二進制文件

二進制文件

原則上講,所有文件都是由8位的字節組成的

如果文件字節中的內容應被解釋為字符,則文件被稱為文本文件;如果被解釋為其它含義,則文件被稱為二進制文件

例如文字處理程序,例如字處理軟件Word產生的doc文件中,數據要被解釋為字體、格式、圖形和其他非字符信息。因此,這樣的文件是二進制文件,不能用Reader流正確讀取

為什么需要二進制文件?

輸入輸出更快

比文本文件小很多

有些數據不容易被表示為字符

抽象類OutputStream

派生類FileOutputStream

用于一般目的輸出(非字符輸出)

用于成組字節輸出

派生類DataOutputStream

具有寫各種基本數據類型的方法

將數據寫到另一個輸出流

它在所有的計算機平臺上使用同樣的數據格式

其常用的一些方法見下表

例:將三個int型數字255/0/-1寫入數據文件data1.dat

public class ext6_7 {    public static void main(String[] args) {        String fileName = "c:/data1.dat";        int value0 = 255, value1 = 0, value2 = -1;        try {            DataOutputStream out = new DataOutputStream(                    new FileOutputStream(fileName));            out.writeInt(value0);            out.writeInt(value1);            out.writeInt(value2);            out.close();        } catch (IOException ex) {            System.out.println("Problem writing " + fileName);        }    }}

說明:

FileOutputStream類的構造方法負責打開文件“data1.dat”用于寫數據

FileOutputStream類的對象與DataOutputStream對象連接,寫基本類型的數據

BufferedOutputStream

寫二進制文件的緩沖流類

類似于文本文件中的BufferedWriter

對于大量數據的寫入,可提高效率

用法示例:

DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream( fileName ) ) ); 

例:向文件中寫入各種數據類型的數,并統計寫入的字節數

public class ex6_8 {    public static void main(String[] args) throws IOException {        String fileName = "c:/mixedTypes.dat";        DataOutputStream dataOut = new DataOutputStream(                new BufferedOutputStream(                        new FileOutputStream(fileName)));        dataOut.writeInt(0);        System.out.println(dataOut.size() + "bytes have been written.");        dataOut.writeDouble(31.2);        System.out.println(dataOut.size() + "bytes have been written.");        dataOut.writeBytes("java");        System.out.println(dataOut.size() + "bytes have been written.");        dataOut.close();    }}

讀二進制文件

過濾流

讀或寫的同時對數據進行處理

通過另外一個流來構造一個過濾流

大部分java.io 包所提供過濾流都是FilterInputStream和FilterOutputStream的子類:

DataInputStream 和 DataOutputStream

BufferedInputStream 和 BufferedOutputStream

LineNumberInputStream

PushbackInputStream

PrintStream

讀取上面的例子創建的數據文件中的3個int型數字,顯示相加結果

public class ex6_10 {    public static void main(String[] args) {        String fileName = "C://data1.dat";        int sum = 0;        try {            DataInputStream instr = new DataInputStream(                    new BufferedInputStream(new FileInputStream(fileName)));            sum += instr.readInt();            sum += instr.readInt();            sum += instr.readInt();            System.out.println("The sum is: " + sum);            instr.close();        } catch (IOException ex) {            System.out.println("Problem reading " + fileName);        }    }}

分析:

readInt方法可以從輸入流中讀入4個字節并將其當作int型數據

由于知道文件中存儲的是3個int型數據,所以使用了3個讀入語句

如果不知道數據的個數該怎么辦呢?因為DataInputStream的讀入操作如遇到文件結尾就會拋出EOFException異常,所以我們可以將讀操作放入try塊中

將讀操作放入try塊中,使遇到文件結尾就會拋出EOFException異常,進入到相應的catch塊中

try{   while(true) sum += instr.readInt();}catch ( EOFException  eof ){   System.out.println("The sum is: " + sum);   instr.close();}
File類

表示磁盤文件信息

定義了一些與平臺無關的方法來操縱文件

–創建、刪除文件

–重命名文件

–判斷文件的讀寫權限及是否存在

–設置和查詢文件的最近修改時間等

構造文件流可以使用File類的對象作為參數

File類常用方法:

例:在C盤創建文件Hello.txt,如果存在則刪除舊文件,不存在則直接創建新的

public class ex6_13 {    public static void main(String[] args) {        File f = new  File("C:" + File.separator + "hello.txt");        if(f.exists()) {            f.delete();        } else {            try {                f.createNewFile();            } catch (Exception e) {                System.out.println(e.getMessage());            }        }    }}
處理壓縮文件

壓縮流類

–java.util.zip包中提供了一些類,使我們可以以壓縮格式對流進行讀寫

–它們都繼承自字節流類OutputStream和InputStream

–其中GZIPOutputStream和ZipOutputStream可分別把數據壓縮成GZIP格式和Zip格式

–GZIPInputStream和ZipInputStream可以分別把壓縮成GZIP格式或Zip的數據解壓縮恢復原狀

public class ex6_14 {    public static void main(String[] args) throws IOException{        FileInputStream in = new FileInputStream("c:/Hello.txt");        GZIPOutputStream out = new GZIPOutputStream(    //生成壓縮文件test.gz                new FileOutputStream("c:/test.gz"));        System.out.println("Writing compressing file from" +                "c:/Hello.txt to c:/test.gz");        int c;        while((c = in.read()) != -1) {            out.write(c);        }        in.close();        out.close();        System.out.println("Reading file form c:/test.gz to monitor");        BufferedReader in2 = new BufferedReader(                new InputStreamReader(                        new GZIPInputStream(                                new FileInputStream("c:/test.gz"))));        String s;        while((s = in2.readLine()) != null) System.out.println(s);        in2.close();        System.out.println("Writing decompression to c:/newHello.txt");        GZIPInputStream in3 = new GZIPInputStream(    //讀取test.gz中的內容                new FileInputStream("c:/test.gz"));        FileOutputStream out2 = new FileOutputStream("c:/newHello.txt");        while((c = in3.read()) != -1) out2.write(c);        in3.close();        out2.close();    }}

Zip文件

–可能含有多個文件,所以有多個入口(Entry)

–每個入口用一個ZipEntity對象表示,該對象的getName()方法返回文件的最初名稱

ZipOutputStream

–父類是DeflaterOutputStream

–可以把數據壓縮成ZIP格式

ZipInputStream

–父類是InflaterInputStream

–可以把壓縮成ZIP格式的數據解壓縮

例:指定若干文件名,將所有文件壓縮為"c:/test.zip",再從此壓縮文件中解壓縮并顯示

public class ex6_15 {    public static void main(String[] args) throws IOException {        ZipOutputStream out = new ZipOutputStream(                new BufferedOutputStream(                        new FileOutputStream("c:/test.zip")));        String[] s = {"c:/t1.txt", "c:/t2.txt", "c:/t3.txt"};  //文件路徑        for(int i = 0; i < s.length; i++) {            System.out.println("Writing file" + s[i]);            BufferedInputStream in = new BufferedInputStream(                    new FileInputStream(s[i]));            out.putNextEntry(new ZipEntry(s[i]));            int c;            while((c = in.read()) != -1) out.write(c);            in.close();        }        out.close();        System.out.println("Reading file");        ZipInputStream in2 = new ZipInputStream(                new BufferedInputStream(                        new FileInputStream("c:/test.zip")));        ZipEntry ze;        while((ze = in2.getNextEntry()) != null) {            System.out.println("Reading file " + ze.getName());            int x;            while((x = in2.read()) != -1) System.out.write(x);            System.out.println();        }        in2.close();    }}

再看一個例子:解壓縮Zip文件,并恢復其原來路徑

class Unzip {    byte[] doc = null;    ;   //存儲解壓縮數據的緩沖字節數組    String FileName = null;    //壓縮文件名字符串    String UnZipPath = null;    //解壓縮路徑字符串     public Unzip(String filename, String unZipPath) {        this.FileName = filename;        this.UnZipPath = unZipPath;        this.setUnZipPath(this.UnZipPath);    }    public Unzip(String filename) {        this.FileName = new String(filename);        this.UnZipPath = null;        this.setUnZipPath(this.UnZipPath);    }    private void setUnZipPath(String unZipPath) {        if(unZipPath.endsWith("http://"))            this.UnZipPath = new String(unZipPath);        else            this.UnZipPath = new String(unZipPath + "http://");    }    public void doUnZip() {        try {            ZipInputStream zipis = new ZipInputStream(                    new FileInputStream(FileName));            ZipEntry fEntry = null;            while((fEntry = zipis.getNextEntry()) != null) {                if(fEntry.isDirectory()) {                    checkFilePath(UnZipPath + fEntry.getName());                } else {    //是文件則解壓縮文件                    String fname = new String(UnZipPath + fEntry.getName());                    try {                        FileOutputStream out = new FileOutputStream(fname);                        doc = new byte[512];                        int n;                        while((n = zipis.read(doc, 0, 512)) != -1) {                            out.write(doc, 0, n);                        }                        out.close();                        out = null;                        doc = null;                    } catch (Exception ex) {                                            }                    }            }            zipis.close();    //關閉輸入流        } catch (IOException ioe) {            System.out.println(ioe);        }    }    private void checkFilePath(String dirName) {        File dir = new File(dirName);        if(!dir.exists())            dir.mkdirs();    }}public class ex6_16 {    public static void main(String[] args) {        String zipFile = "c:/test.zip";        String unZipPath = "";        Unzip myZip = new Unzip(zipFile, unZipPath);        myZip.doUnZip();    }}
對象序列化

保存對象的信息,在需要的時候,再讀取這個對象

內存中的對象在程序結束時就會被垃圾回收機制清除

用于對象信息存儲和讀取的輸入輸出流類:

ObjectInputStream、ObjectOutputStream

實現對象的讀寫

通過ObjectOutputStream把對象寫入磁盤文件

通過ObjectInputStream把對象讀入程序

–不保存對象的transient和static類型的變量

–對象要想實現序列化,其所屬的類必須實現Serializable接口

必須通過另一個流構造ObjectOutputStream:

FileOutputStream out = new FileOutputStream("theTime");                   ObjectOutputStream s =  new ObjectOutputStream(out);s.writeObject("Today");s.writeObject(new Date());s.flush();

必須通過另一個流構造ObjectInputStream:

FileInputStream in = new FileInputStream("theTime");ObjectInputStream s = new ObjectInputStream(in);String today = (String)s.readObject();Date date = (Date)s.readObject();

空接口,使類的對象可實現序列化

Serializable 接口的定義:

package java.io;public interface Serializable {    // there's nothing in here!};

實現Serializable接口的語句

public class MyClass implements Serializable {    ...}

使用關鍵字transient可以阻止對象的某些成員被自動寫入文件

看一個例子:

創建一個書籍對象,并把它輸出到一個文件book.dat中,然后再把該對象讀出來,在屏幕上顯示對象信息

class Book implements Serializable {    int id;    String name;    String author;    float price;    public Book(int id, String name, String author, float price) {        this.id = id;        this.name = name;        this.author = author;        this.price = price;    }}public class ex6_17 {    public static void main(String[] args) throws IOException, ClassNotFoundException {        Book book = new Book(100000, "java programming", "Wu", 23);        ObjectOutputStream oos = new ObjectOutputStream(                new FileOutputStream("c:/book.dat"));        oos.writeObject(book);        oos.close();        System.out.println("ID is: " + book.id);        System.out.println("name is: " + book.name);        System.out.println("author is: " + book.author);        System.out.println("price is: " + book.price);    }}

Externalizable 接口

–實現該接口可以控制對象的讀寫

–API中的說明為

public interface Externalizable extends Serializable

–其中有兩個方法writeExternal()和readExternal(),因此實現該接口的類必須實現這兩個方法

–ObjectOutputStream的writeObject()方法只寫入對象的標識,然后調用對象所屬類的writeExternal()

–ObjectInputStream的readObject()方法調用對象所屬類的readExternal()

隨機文件讀寫

RandomaccessFile類

–可跳轉到文件的任意位置讀/寫數據

–可在隨機文件中插入數據,而不破壞該文件的其他數據

–實現了DataInput 和 DataOutput 接口,可使用普通的讀寫方法

–有個位置指示器,指向當前讀寫處的位置。剛打開文件時,文件指示器指向文件的開頭處。對文件指針顯式操作的方法有:

int skipBytes(int n):把文件指針向前移動指定的n個字節

void seek(long):移動文件指針到指定的位置。

long getFilePointer():得到當前的文件指針。

–在等長記錄格式文件的隨機讀取時有很大的優勢,但僅限于操作文件,不能訪問其它IO設備,如網絡、內存映像等

–可用來實現讀和寫,構造方法包括
public RandomAccessFile(File file,String mode) throws FileNotFoundExceptionpublic RandomAccessFile(String name, String mode) throws FileNotFoundException
–建立一個RandomAccessFile時,要指出你要執行的操作:僅從文件讀,還是同時讀寫
new RandomAccessFile("farrago.txt", "r");new RandomAccessFile("farrago.txt", "rw");

RandomAccessFile類常用API

例:創建一個雇員類,包括姓名、年齡。姓名不超過8個字符,年齡是int類型。每條記錄固定為20個字節。使用RandomAccessFile向文件添加、修改、讀取雇員信息

class Employee {    char name[] = {'/u0000', '/u0000','/u0000', '/u0000',            '/u0000', '/u0000', '/u0000', '/u0000'};    int age;    public Employee(String name, int age) throws Exception {        if(name.toCharArray().length > 8)            System.arraycopy(name.toCharArray(), 0, this.name, 0, 8);        else            System.arraycopy(name.toCharArray(), 0, this.name, 0, name.toCharArray().length);        this.age = age;    }}public class ex6_18 {    String FileName;    public ex6_18(String FileName) {        this.FileName = FileName;    }    public void writeEmployee(Employee e, int n) throws Exception {        RandomAccessFile ra = new RandomAccessFile(FileName, "rw");        ra.seek(n * 20);    //將位置指示器移到指定位置上        for(int i = 0; i < 8; i++) ra.writeChar(e.name[i]);        ra.writeInt(e.age);        ra.close();    }    public void readEmployee(int n) throws Exception {        char buf[] = new char[8];        RandomAccessFile ra = new RandomAccessFile(FileName, "r");        ra.seek(n * 20);        for(int i = 0; i < 8; i++) buf[i] = ra.readChar();        System.out.print("name: ");        System.out.println(buf);        System.out.println("age: " + ra.readInt());        ra.close();    }    public static void main(String[] args) throws Exception {        ex6_18 t = new ex6_18("c:/temp.txt");        Employee e1 = new Employee("zhangsan", 22);        Employee e2 = new Employee("lisi", 20);        Employee e3 = new Employee("wangwu", 25);        t.writeEmployee(e1, 0);        t.writeEmployee(e3, 2);        System.out.println("第1個雇員的信息");        t.readEmployee(0);        System.out.println("第3個雇員的信息");        t.readEmployee(2);        System.out.println("第2個雇員的信息");        t.readEmployee(1);    }}

您還可能感興趣:

java學習筆記系列:

java學習筆記15--多線程編程基礎2

java學習筆記14--多線程編程基礎1

java學習筆記13--反射機制與動態代理

java學習筆記12--異常處理

java學習筆記11--集合總結

java學習筆記10--泛型總結

java學習筆記9--內部類總結

java學習筆記8--接口總結

java學習筆記7--抽象類與抽象方法

java學習筆記6--類的繼承、Object類

java學習筆記5--類的方法

java學習筆記4--對象的初始化與回收

java學習筆記3--類與對象的基礎

java學習筆記2--數據類型、數組

java學習筆記1--開發環境平臺總結


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东莞市| 涞源县| 额敏县| 侯马市| 乌苏市| 淮阳县| 天柱县| 黔南| 溧阳市| 岚皋县| 车致| 巴彦淖尔市| 府谷县| 峡江县| 黔江区| 永康市| 五华县| 东丰县| 萨嘎县| 云阳县| 阿瓦提县| 车致| 平定县| 永顺县| 兴仁县| 松滋市| 桦南县| 马鞍山市| 崇州市| 渑池县| 贵港市| 平江县| 揭东县| 偏关县| 延长县| 化隆| 海原县| 临颍县| 屏东县| 汤原县| 庄浪县|