Java的I/O操作

來源:互聯網
上載者:User

標籤:

一、概述

  Java的IO支援通過java.io包下的類和介面來完成,在java.io包下主要有包括輸入、輸出兩種IO流,每種輸入輸出資料流又可分為位元組流和字元流兩大類。從JDK1.4以後,Java在java.nio包下提供了系列的全新API,通過java.nio,程式可以更高效的進行輸入、輸出操作。

二、Java I/O類和介面 
  1. File類

  File類直接處理檔案和檔案系統,它沒有指定如何擷取資訊或將資訊儲存到檔案中,只描述了檔案本身的屬性。File對象用於獲得或者操作與磁碟檔案相關聯的資訊,如存取許可權、時間、日期和目錄路徑等,並且還可以瀏覽子目錄的階層。

下面的建構函式可用來建立File對象:

構造方法摘要
File(File parent, String child)
          根據 parent 抽象路徑名和 child 路徑名字串建立一個新 File 執行個體。
File(String pathname)
          通過將給定路徑名字串轉換為抽象路徑名來建立一個新 File 執行個體。
File(String parent, String child)
          根據 parent 路徑名字串和 child 路徑名字串建立一個新 File 執行個體。
File(URI uri)
          通過將給定的 file: URI 轉換為一個抽象路徑名來建立一個新的 File 執行個體。

  File類定義了許多可以得到File對象標準屬性的方法

public class Demo{    public static void main(String[] args)    {        File f=new File("D://hello.java");        System.out.println(f.getParent());//返回此抽象路徑名父目錄的路徑名字串;如果此路徑名沒有指定父目錄,則返回 null        System.out.println(f.getName());//返回由此抽象路徑名表示的檔案或目錄的名稱        System.out.println(f.exists());//測試此抽象路徑名表示的檔案或目錄是否存在        System.out.println(f.getAbsoluteFile());// 返回此抽象路徑名的絕對路徑名形式        System.out.println(f.getAbsolutePath());//返回此抽象路徑名的規範路徑名字串        System.out.println(f.getPath());//將此抽象路徑名轉換為一個路徑名字串        System.out.println(f.hashCode());//計算此抽象路徑名的雜湊碼        System.out.println(f.length());//返回由此抽象路徑名表示的檔案的長度        System.out.println(f.list());// 返回一個字串數組,這些字串指定此抽象路徑名表示的目錄中的檔案和目錄        System.out.println(f.mkdir());//建立此抽象路徑名指定的目錄    }}
  2. 流類

  Java中把不同的輸入輸出源抽象畫為“流”,通過流的方式允許?Java程式使用相同的方式來訪問不同的輸入輸出源。

  位元組流類:提供了處理針對位元組的IO的豐富環境,頂部類是InputStream和OutputStream,它們均是抽象類別。

  字元流類:位元組流類不能處理Unicode字元,字元流類操作的資料單元為字元,,頂部類是Reader和Writer。

  位元組流類和字元流類的功能基本一樣,只是操作的資料單元不同,其中InputStream和Reader都是將資料抽象為一根水管,程式可以通過read()方法每次抽取一個“水滴”,也可以通過read(char[] cbuf)方法來讀取多個“水滴”,程式通過read()方法返回-1來判斷是否到了輸入資料流的結束點。

  eg.讀取檔案,統計檔案字元數:

public class FileDemo{    public static void main(String[] args)    {        int b=0;        try        {            FileInputStream in=null;            in =new FileInputStream("D:\\a.txt");            long num=0;            while((b=in.read())!=-1)            {                System.out.print((char)b);                num++;            }            in.close();                System.out.println(num);        }         catch (FileNotFoundException e)        {            e.printStackTrace();        }        catch (IOException e)        {            e.printStackTrace();        }            }}

  FileInputStream類建立一個InputStream,可以用來從檔案中讀取檔案。

  eg.將一個檔案內容拷貝至另一個檔案:

public class FileOutStream{    public static void main(String[] args)    {        int b=0;        try        {            FileInputStream in =new FileInputStream("D:\\Eclipse\\workSpace\\day_041602\\src\\day_041602\\TestMain.java");            FileOutputStream out=new FileOutputStream("D:\\hello.java");            while((b=in.read())!=-1)            {                out.write(b);            }            in.close();            out.close();            System.out.println("執行完成");        }         catch (FileNotFoundException e)        {            // TODO 自動產生的 catch 塊            e.printStackTrace();        } catch (IOException e)        {            // TODO 自動產生的 catch 塊            e.printStackTrace();        }    }}

  BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter稱為緩衝流,它們通過緩衝輸入輸出來提高效能。

  eg.在hello.java文本中輸入100個隨機數,並在螢幕上顯示:

public class BufferWriterDemo{    public static void main(String[] args)    {        try        {            String s;            BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\hello.java"));            BufferedReader br=new BufferedReader(new FileReader("D:\\hello.java"));            for(int i=0;i<100;i++)            {                s=String.valueOf(Math.random());  //產生隨機數                bw.write(s);//寫入hello.java檔案中                bw.newLine();//寫入一個分行符號            }            bw.flush();//重新整理緩衝            while((s=br.readLine()) != null)//讀取一個文本行                {                        System.out.println(s);                }            bw.close();            br.close();        }         catch (IOException e)        {            // TODO 自動產生的 catch 塊            e.printStackTrace();        }    }}
 三、NIO  1.概述

  NIO使用記憶體映射的方式處理輸入輸出,將檔案或檔案的一段區域對應到記憶體中,這樣就可以像訪問記憶體一樣來訪問檔案了。

  相關的包有:java.nio.channels包:主要包含Channel和Selector相關的類,java.nio.charset包:主要包含和字元集相關的類

  NIO系基於兩個基本的元素:緩衝和通道。緩衝區容納資料,通道代表隊I/O裝置的開放式串連。一般而言使用NIO系統,需要獲得到I?O裝置的一個通道和容納資料的一個緩衝區,然後可以對緩衝區進行操作,隨意輸入和輸出資料。除此之外,NIO還提供了用於將Unicode字串映射成位元組序列以及逆映射操作的Charset類,還有支援非阻塞式輸入輸出的Selector類。

  2.緩衝區

   緩衝(buffer)可以理解成一個容器,它的本質是一個數組,發送到Channel中的所有對象都必須首先放到buffer中,從channel中讀取的資料也必須先讀到buffer中。

   Buffer中有三個重要的參數:

    • capacity:表示該Buffer的最大儲存容量
    • limit:第一個不應該被讀出或寫入的緩衝區位置索引
    • position:用於指明下一個可以被讀出或寫入的緩衝區位置索引

    除此之外還有一個可選的mark標記,該mark允許程式直接將position定位到mark處。位置如下所示:

  

    每放入一個資料,position向後移動一位,當Buffer裝入資料結束後,調用flip方法,將limit設定為position所在的位置,將position設定為0,這樣使得從Buffer中讀資料總是從0開始。當Buffer輸出資料結束後,Buffer調用 clear方法,它將position置為0,,置limit為capacity,這樣為再次向Buffer中裝入資料做好準備。Buffer還提供了put和get方法,用於向Buffer中放入資料和讀取資料,既支援對單個資料的訪問也支援對批量資料的訪問。

  eg.

public class Test{    public static void main(String[] args)    {        CharBuffer m=CharBuffer.allocate(8);        m.put(‘a‘);        m.put(‘b‘);        m.put(‘c‘);        System.out.println("position:"+m.position());        System.out.println("limit:"+m.limit());        m.flip();        System.out.println("第一個元素"+m.get());        System.out.println("第二個元素"+m.get());        System.out.println("position:"+m.position());    }}

   執行結果:

  

 3.通道

   Channel與傳統的InputStream、OutputStream最大的區別在於它提供了一個map方法,通過該map方法可以直接將一塊資料對應到記憶體中。

     Channel是一個介面,系統為該介面提供了FileChannel等實作類別,所有的Channel都是通過傳統節點InputStream、OutputSteam的getChannel方法來返回對應的Channel。

   Channel中最常見的三個方法是:map、read和write。其中map將Channel對應的部分或全部資料對應的ByteBuffer,read或write方法有一系列重載的形式用於讀取資料。

  eg.將WelcomeServlet.java的內容複寫到a.txt中去,並在控制台列印處內容。

public class FileChannelTest{    public static void main(String[] args)    {        FileChannel inChannel=null;        FileChannel outChannel=null;        FileChannel randomChannel=null;        File f=new File("D://WelcomeServlet.java");        try        {            FileInputStream fs=new FileInputStream(f);            inChannel=fs.getChannel();                        MappedByteBuffer buffer=inChannel.map(FileChannel.MapMode.READ_ONLY,0, f.length());//將inChannel裡的全部資料對應成ByteBuffer            Charset charset=Charset.forName("GBK");            outChannel=new FileOutputStream("D://a.txt").getChannel();                        outChannel.write(buffer);            buffer.clear();                        CharsetDecoder decoder=charset.newDecoder();//建立解碼器對象            CharBuffer charBuffer=decoder.decode(buffer);//使用解碼器將ByteBuffer轉換為charBuffer            System.out.println(charBuffer);     //擷取對應字串        }         catch (FileNotFoundException e)        {            // TODO 自動產生的 catch 塊            e.printStackTrace();        }         catch (IOException e)        {            // TODO 自動產生的 catch 塊            e.printStackTrace();        }    }}

 

 

 

 

 

 

 

 

 

  

  

 

  

Java的I/O操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.