Java IO詳解

概述

IO流用來處理設備之間的數據傳輸,Java對數據的操做是經過流的方式,Java用於操做流的對象都在IO包中。java

流按操做數據分爲兩種:字節流與字符流
流按流向分爲:輸入流、輸出流數組

IO流經常使用基類

字符流的抽象基類

Reader
Writer函數

注:由這四個類派生出來的子類名稱都是以其父類名做爲子類名的後綴
如:InputStream的子類FileInputStream大數據

如:Reader的子類FileReadercode

字節流的抽象基類

InputStream
OutputStream對象

字符流操做

FileWriter字符流寫入

FileWriter 後綴是父類名 前綴名是功能圖片

FileWriter寫文件步驟:ip

  1. 建立一個FileWrite對象,該對象一初始化就必需要明確被操做的文件,並且該文件會被建立到指定目錄,若是該目錄下已有同名文件則被覆蓋FileWrite fw = new FileWrite("demo.txt")內存

  2. 調用write方法將字符串寫入到流中fw.write("abcde");資源

  3. 刷新流對象中的緩衝中的數據,將數據刷到目的地中
    fw.flush();//flush刷新後,流能夠繼續使用,close刷新後,流將會關閉

fw.close();//關閉流資源,但關閉以前會刷新一次內部的緩衝中的數據,最後必需要關閉流

代碼示例

/*
需求:在硬盤上,建立一個文件並寫入一些文字數據。
找到一個專門用於操做文件的Writer子類對象。FileWriter。  後綴名是父類名。 前綴名是該流對象的功能。
*/
import java.io.*;
class  FileWriterDemo
{
    public static void main(String[] args) throws IOException
    {
        //建立一個FileWriter對象。該對象一被初始化就必需要明確被操做的文件。
        //並且該文件會被建立到指定目錄下。若是該目錄下已有同名文件,將被覆蓋。
        //其實該步就是在明確數據要存放的目的地。
        FileWriter fw = new FileWriter("demo.txt");
        //調用write方法,將字符串寫入到流中。
        fw.write("abcde");
        //刷新流對象中的緩衝中的數據。
        //將數據刷到目的地中。
        //fw.flush();
        //關閉流資源,可是關閉以前會刷新一次內部的緩衝中的數據。
        //將數據刷到目的地中。
        //和flush區別:flush刷新後,流能夠繼續使用,close刷新後,會將流關閉。
        fw.close();
    }
}

/*
演示對已有文件的數據續寫。
*/
import java.io.*;
class  FileWriterDemo3
{
    public static void main(String[] args) throws IOException  //不能拋,要處理異常//傳遞一個true參數,表明不覆蓋已有的文件。並在已有文件的末尾處進行數據續寫。
        FileWriter fw = new FileWriter("demo.txt",true);
        fw.write("nihao\r\nxiexie");  //換行續寫
        fw.close();
    }
}

FileReader字符流讀取

import java.io.*;
class  FileReaderDemo
{
    public static void main(String[] args) throws IOException
    {
        //建立一個文件讀取流對象,和指定名稱的文件相關聯。
        //要保證該文件是已經存在的,若是不存在,會發生異常FileNotFoundException
        FileReader fr = new FileReader("demo.txt");
        //調用讀取流對象的read方法。
        //read():一次讀一個字符。並且會自動往下讀。        
        int ch = 0;
        while((ch=fr.read())!=-1)
        {
            System.out.println("ch="+(char)ch);
        }
        /*
        while(true)
        {
            int ch = fr.read();
            if(ch==-1)
                break;
            System.out.println("ch="+(char)ch);
        }
        */
        fr.close();
    }
}
/*
第二種方式:經過字符數組進行讀取。 
  經常使用這種
*/
import java.io.*;
class FileReaderDemo2 
{
    public static void main(String[] args) throws IOException
    {
        FileReader fr = new FileReader("demo.txt");
        
        //定義一個字符數組。用於存儲讀到字符。
        //該read(char[])返回的是讀到字符個數。
        char[] buf = new char[1024];
        int num = 0;
        while((num=fr.read(buf))!=-1)
        {
            System.out.println(new String(buf,0,num));
        }
        
        fr.close();
    }
}

文件拷貝

//將C盤一個文本文件複製到D盤。
/*
複製的原理:
其實就是將C盤下的文件數據存儲到D盤的一個文件中。
步驟:
1,在D盤建立一個文件。用於存儲C盤文件中的數據。
2,定義讀取流和C盤文件關聯。
3,經過不斷的讀寫完成數據存儲。
4,關閉資源。
*/
import java.io.*;
class CopyText 
{
    public static void main(String[] args) throws IOException
    {
        copy_2();
    }
    public static void copy_2()
    {
        FileWriter fw = null;
        FileReader fr = null;
        try
        {
            fw = new FileWriter("SystemDemo_copy.txt");
            fr = new FileReader("SystemDemo.java");
            char[] buf = new char[1024];
            int len = 0;
            while((len=fr.read(buf))!=-1)
            {
                fw.write(buf,0,len);
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("讀寫失敗");
        }
        finally
        {
            if(fr!=null)
                try
                {
                    fr.close();
                }
                catch (IOException e)
                {
                }
            if(fw!=null)
                try
                {
                    fw.close();
                }
                catch (IOException e)
                {
                }
        }
    }
    //從C盤讀一個字符,就往D盤寫一個字符。
    public static void copy_1()throws IOException
    {
        //建立目的地。
        FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
        //與已有文件關聯。
        FileReader fr = new FileReader("RuntimeDemo.java");
        int ch = 0;
        while((ch=fr.read())!=-1)
        {
            fw.write(ch);
        }
        
        fw.close();
        fr.close();
    }
}

BufferedReader字符流緩衝區讀

從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取
能夠指定緩衝區的大小,或者可使用默認大小。大多數狀況下,默認值就足夠大了

/*
字符讀取流緩衝區:
該緩衝區提供了一個一次讀一行的方法 readLine,方便於對文本數據的獲取。
當返回null時,表示讀到文件末尾。
readLine方法返回的時候只返回回車符以前的數據內容。並不返回回車符。
*/
import java.io.*;
class  BufferedReaderDemo
{
    public static void main(String[] args) throws IOException
    {
        //建立一個讀取流對象和文件相關聯。
        FileReader fr = new FileReader("buf.txt");
        //爲了提升效率。加入緩衝技術。將字符讀取流對象做爲參數傳遞給緩衝對象的構造函數。
        BufferedReader bufr = new BufferedReader(fr);
        
        String line = null;
        while((line=bufr.readLine())!=null)
        {
            System.out.print(line);
        }
        bufr.close();
    }
}

BufferedWriter字符流緩衝區讀

將文本寫入字符輸出流,緩衝各個字符,從而提供單個字符、數組和字符串的高效寫入
能夠指定緩衝區的大小,或者接受默認的大小。在大多數狀況下,默認值就足夠大了
一般 Writer 將其輸出當即發送到底層字符或字節流。除非要求提示輸出,不然建議用 BufferedWriter 包裝全部其 write() 操做可能開銷很高的 Writer(如 FileWriters 和 OutputStreamWriters)。

/*
緩衝區的出現是爲了提升流的操做效率而出現的。
因此在建立緩衝區以前,必需要先有流對象。
該緩衝區中提供了一個跨平臺的換行符。
newLine();
*/
import java.io.*;
class  BufferedWriterDemo
{
    public static void main(String[] args) throws IOException
    {
        //建立一個字符寫入流對象。
        FileWriter fw = new FileWriter("buf.txt");
        //爲了提升字符寫入流效率。加入了緩衝技術。
        //只要將須要被提升效率的流對象做爲參數傳遞給緩衝區的構造函數便可。
        BufferedWriter bufw = new BufferedWriter(fw);
        for(int x=1; x<5; x++)
        {
            bufw.write("abcd"+x);
            bufw.newLine(); //寫入一個行分隔符
            bufw.flush();
        }
        //記住,只要用到緩衝區,就要記得刷新。
        //bufw.flush();
        //其實關閉緩衝區,就是在關閉緩衝區中的流對象。
        bufw.close();
    }
}

經過緩衝區複製文本

/*
經過緩衝區複製一個.java文件。
*/
import java.io.*;
class  CopyTextByBuf
{
    public static void main(String[] args) 
    {
        BufferedReader bufr = null;
        BufferedWriter bufw = null;
        try
        {
            bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
            bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
            String line = null;
            while((line=bufr.readLine())!=null)
            {
                bufw.write(line);
                bufw.newLine();
                bufw.flush();
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("讀寫失敗");
        }
        finally
        {
            try
            {
                if(bufr!=null)
                    bufr.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("讀取關閉失敗");
            }
            try
            {
                if(bufw!=null)
                    bufw.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("寫入關閉失敗");
            }
        }
    }
}
}

字節流操做

FileInputStream 從文件系統中的某個文件中得到輸入字節。哪些文件可用取決於主機環境。
FileInputStream 用於讀取諸如圖像數據之類的原始字節流。要讀取字符流,請考慮使用 FileReader。

FileOutputStream文件輸出流是用於將數據寫入 File 或 FileDescriptor 的輸出流。文件是否可用或可否能夠被建立取決於基礎平臺。特別是某些平臺一次只容許一個 FileOutputStream(或其餘文件寫入對象)打開文件進行寫入。在這種狀況下,若是所涉及的文件已經打開,則此類中的構造方法將失敗。
FileOutputStream 用於寫入諸如圖像數據之類的原始字節的流。要寫入字符流,請考慮使用 FileWriter。

FileInputStream和FileOutputStream

字節流:
InputStream  OutputStream
需求,想要操做圖片數據。這時就要用到字節流。
複製一個圖片.
*/
import java.io.*;
class  FileStream
{
    public static void main(String[] args) throws IOException
    {
        readFile_3();
    }
    public static void readFile_3()throws IOException
    {
        FileInputStream fis = new FileInputStream("fos.txt");
        
//        int num = fis.available();
        byte[] buf = new byte[fis.available()];//定義一個剛恰好的緩衝區。不用在循環了。
        fis.read(buf);
        System.out.println(new String(buf));
        fis.close();
    }
    public static void readFile_2()throws IOException
    {
        FileInputStream fis = new FileInputStream("fos.txt");
        byte[] buf = new byte[1024];
        int len = 0;
        while((len=fis.read(buf))!=-1)
        {
            System.out.println(new String(buf,0,len));
        }
        fis.close();
        
    }
    public static void readFile_1()throws IOException
    {
        FileInputStream fis = new FileInputStream("fos.txt");
        int ch = 0;
        while((ch=fis.read())!=-1)
        {
            System.out.println((char)ch);
        }
        fis.close();
    }
    public static void writeFile()throws IOException
    {
        FileOutputStream fos = new FileOutputStream("fos.txt");
        
        fos.write("abcde".getBytes());
        fos.close();
        
    }
}

複製圖片

/*
複製一個圖片
思路:
1,用字節讀取流對象和圖片關聯。
2,用字節寫入流對象建立一個圖片文件。用於存儲獲取到的圖片數據。
3,經過循環讀寫,完成數據的存儲。
4,關閉資源。
*/
import java.io.*;
class  CopyPic
{
    public static void main(String[] args) 
    {
        FileOutputStream fos = null;
        FileInputStream fis = null;
        try
        {
            fos = new FileOutputStream("c:\\2.bmp");
            fis = new FileInputStream("c:\\1.bmp");
            byte[] buf = new byte[1024];
            int len = 0;
            while((len=fis.read(buf))!=-1)
            {
                fos.write(buf,0,len);
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("複製文件失敗");
        }
        finally
        {
            try
            {
                if(fis!=null)
                    fis.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("讀取關閉失敗");
            }
            try
            {
                if(fos!=null)
                    fos.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("寫入關閉失敗");
            }
        }
    }
}

字節流的緩衝區

/*
演示mp3的複製。經過緩衝區。
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class  CopyMp3
{
    public static void main(String[] args) throws IOException
    {
        long start = System.currentTimeMillis();
        copy_2();
        long end = System.currentTimeMillis();
        System.out.println((end-start)+"毫秒");
    }
    public static void copy_2()throws IOException
    {
        MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));
        
        int by = 0;
        //System.out.println("第一個字節:"+bufis.myRead());
        while((by=bufis.myRead())!=-1)
        {
            bufos.write(by);
        }
        bufos.close();
        bufis.myClose();
    }
    //經過字節流的緩衝區完成複製。
    public static void copy_1()throws IOException
    {
        BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
        
        int by = 0;
        while((by=bufis.read())!=-1)
        {
            bufos.write(by);
        }
        bufos.close();
        bufis.close();
        
    }
}

打印流

字節打印流PrintStream

構造函數能夠接收的參數類型:

  1. File對象。File

  2. 字符串路徑。String

  3. 字節輸出流。OutputStream

字符打印流PrintWriter

構造函數能夠接收的參數類型:

  1. File對象。File

  2. 字符串路徑。String

  3. 字節輸出流。OutputStream

  4. 字符輸出流,Writer。

示例

/*
在沒有刷新前,你寫入的數據並無真正寫入文件,只是保存在內存中。刷新後纔會寫入文件,若是程序中沒有調用刷新方法,當程序執行完時會自動刷新,也就是隻有到數據所有執行完纔會一次性寫入,大數據量時對運行效率有影響。
建立不具備自動行刷新的對象,就是用這個對象寫入數據時不會自動刷新。
*/
import java.io.*;
class  PrintStreamDemo
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader bufr = 
            new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);
        String line = null;
        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;
            out.println(line.toUpperCase());
            //out.flush();
        }
        out.close();
        bufr.close();
    }    
}
相關文章
相關標籤/搜索