Energy of Love  
          日歷
          <2013年9月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345
          統(tǒng)計(jì)
          • 隨筆 - 70
          • 文章 - 0
          • 評(píng)論 - 80
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

           

          11.3 I/O類使用
                   由于在IO操作中,需要使用的數(shù)據(jù)源有很多,作為一個(gè)IO技術(shù)的初學(xué)者,從讀寫文件開始學(xué)習(xí)IO技術(shù)是一個(gè)比較好的選擇。因?yàn)槲募且环N常見的數(shù)據(jù)源,而且讀寫文件也是程序員進(jìn)行IO編程的一個(gè)基本能力。本章IO類的使用就從讀寫文件開始。
          11.3.1 文件操作
                   文件(File)是 最常見的數(shù)據(jù)源之一,在程序中經(jīng)常需要將數(shù)據(jù)存儲(chǔ)到文件中,例如圖片文件、聲音文件等數(shù)據(jù)文件,也經(jīng)常需要根據(jù)需要從指定的文件中進(jìn)行數(shù)據(jù)的讀取。當(dāng)然, 在實(shí)際使用時(shí),文件都包含一個(gè)的格式,這個(gè)格式需要程序員根據(jù)需要進(jìn)行設(shè)計(jì),讀取已有的文件時(shí)也需要熟悉對(duì)應(yīng)的文件格式,才能把數(shù)據(jù)從文件中正確的讀取出 來(lái)。
                   文件的存儲(chǔ)介質(zhì)有很多,例如硬盤、光盤和U盤等,由于IO類設(shè)計(jì)時(shí),從數(shù)據(jù)源轉(zhuǎn)換為流對(duì)象的操作由API實(shí)現(xiàn)了,所以存儲(chǔ)介質(zhì)的不同對(duì)于程序員來(lái)說(shuō)是透明的,和實(shí)際編寫代碼無(wú)關(guān)。
          11.3.1.1 文件的概念
                   文件是計(jì)算機(jī)中一種基本的數(shù)據(jù)存儲(chǔ)形式,在實(shí)際存儲(chǔ)數(shù)據(jù)時(shí),如果對(duì)于數(shù)據(jù)的讀寫速度要求不是很高,存儲(chǔ)的數(shù)據(jù)量不是很大時(shí),使用文件作為一種持久數(shù)據(jù)存儲(chǔ)的方式是比較好的選擇。
                   存儲(chǔ)在文件內(nèi)部的數(shù)據(jù)和內(nèi)存中的數(shù)據(jù)不同,存儲(chǔ)在文件中的數(shù)據(jù)是一種“持久存儲(chǔ)”,也就是當(dāng)程序退出或計(jì)算機(jī)關(guān)機(jī)以后,數(shù)據(jù)還是存在的,而內(nèi)存內(nèi)部的數(shù)據(jù)在程序退出或計(jì)算機(jī)關(guān)機(jī)以后,數(shù)據(jù)就丟失了。
                   在不同的存儲(chǔ)介質(zhì)中,文件中的數(shù)據(jù)都是以一定的順序依次存儲(chǔ)起來(lái),在實(shí)際讀取時(shí)由硬件以及操作系統(tǒng)完成對(duì)于數(shù)據(jù)的控制,保證程序讀取到的數(shù)據(jù)和存儲(chǔ)的順序保持一致。
                   每個(gè)文件以一個(gè)文件路徑和文件名稱進(jìn)行表示,在需要訪問(wèn)該文件的時(shí),只需要知道該文件的路徑以及文件的全名即可。在不同的操作系統(tǒng)環(huán)境下,文件路徑的表示形式是不一樣的,例如在Windows操作系統(tǒng)中一般的表示形式為C:\windows\system,而Unix上的表示形式為/user/my。所以如果需要讓Java程序能夠在不同的操作系統(tǒng)下運(yùn)行,書寫文件路徑時(shí)還需要比較注意。
          11.3.1.1.1 絕對(duì)路徑和相對(duì)路徑
                   絕對(duì)路徑是指書寫文件的完整路徑,例如d:\java\Hello.java,該路徑中包含文件的完整路徑d:\java以及文件的全名Hello.java。使用該路徑可以唯一的找到一個(gè)文件,不會(huì)產(chǎn)生歧義。但是使用絕對(duì)路徑在表示文件時(shí),受到的限制很大,且不能在不同的操作系統(tǒng)下運(yùn)行,因?yàn)椴煌僮飨到y(tǒng)下絕對(duì)路徑的表達(dá)形式存在不同。
                   相對(duì)路徑是指書寫文件的部分路徑,例如\test\Hello.java,該路徑中只包含文件的部分路徑\test和文件的全名Hello.java,部分路徑是指當(dāng)前路徑下的子路徑,例如當(dāng)前程序在d:\abc下運(yùn)行,則該文件的完整路徑就是d:\abc\test。使用這種形式,可以更加通用的代表文件的位置,使得文件路徑產(chǎn)生一定的靈活性。
                   在Eclipse項(xiàng)目中運(yùn)行程序時(shí),當(dāng)前路徑是項(xiàng)目的根目錄,例如工作空間存儲(chǔ)在d:\javaproject,當(dāng)前項(xiàng)目名稱是Test,則當(dāng)前路徑是:d:\javaproject\Test。在控制臺(tái)下面運(yùn)行程序時(shí),當(dāng)前路徑是class文件所在的目錄,如果class文件包含包名,則以該class文件最頂層的包名作為當(dāng)前路徑。
                   另外在Java語(yǔ)言的代碼內(nèi)部書寫文件路徑時(shí),需要注意大小寫,大小寫需要保持一致,路徑中的文件夾名稱區(qū)分大小寫。由于’\’是Java語(yǔ)言中的特殊字符,所以在代碼內(nèi)部書寫文件路徑時(shí),例如代表“c:\test\java\Hello.java”時(shí),需要書寫成“c:\\test\\java\\Hello.java”或“c:/test/java/Hello.java”,這些都需要在代碼中注意。
          11.3.1.1.2 文件名稱
                   文件名稱一般采用“文件名.后綴名”的形式進(jìn)行命名,其中“文件名”用來(lái)表示文件的作用,而使用后綴名來(lái)表示文件的類型,這是當(dāng)前操作系統(tǒng)中常見的一種形式,例如“readme.txt”文件,其中readme代表該文件時(shí)說(shuō)明文件,而txt后綴名代表文件時(shí)文本文件類型,在操作系統(tǒng)中,還會(huì)自動(dòng)將特定格式的后綴名和對(duì)應(yīng)的程序關(guān)聯(lián),在雙擊該文件時(shí)使用特定的程序打開。
                   其實(shí)在文件名稱只是一個(gè)標(biāo)示,和實(shí)際存儲(chǔ)的文件內(nèi)容沒(méi)有必然的聯(lián)系,只是使用這種方式方便文件的使用。在程序中需要存儲(chǔ)數(shù)據(jù)時(shí),如果自己設(shè)計(jì)了特定的文件格式,則可以自定義文件的后綴名,來(lái)標(biāo)示自己的文件類型。
                   和文件路徑一樣,在Java代碼內(nèi)部書寫文件名稱時(shí)也區(qū)分大小寫,文件名稱的大小寫必須和操作系統(tǒng)中的大小寫保持一致。
                   另外,在書寫文件名稱時(shí)不要忘記書寫文件的后綴名。
          11.3.1.2 File類
                   為了很方便的代表文件的概念,以及存儲(chǔ)一些對(duì)于文件的基本操作,在java.io包中設(shè)計(jì)了一個(gè)專門的類——File類。
                   在File類中包含了大部分和文件操作的功能方法,該類的對(duì)象可以代表一個(gè)具體的文件或文件夾,所以以前曾有人建議將該類的類名修改成FilePath,因?yàn)樵擃愐部梢源硪粋€(gè)文件夾,更準(zhǔn)確的說(shuō)是可以代表一個(gè)文件路徑。
                   下面介紹一下File類的基本使用。
                   1、File對(duì)象代表文件路徑
          File類的對(duì)象可以代表一個(gè)具體的文件路徑,在實(shí)際代表時(shí),可以使用絕對(duì)路徑也可以使用相對(duì)路徑。
          下面是創(chuàng)建的文件對(duì)象示例。
                             public File(String pathname)
                   該示例中使用一個(gè)文件路徑表示一個(gè)File類的對(duì)象,例如:
                             File f1 = new File(“d:\\test\\1.txt”);
                             File f2 = new File(“1.txt”);
                            File f3 = new File(“e:\\abc”);
          這里的f1和f2對(duì)象分別代表一個(gè)文件,f1是絕對(duì)路徑,而f2是相對(duì)路徑,f3則代表一個(gè)文件夾,文件夾也是文件路徑的一種。
          public File(String parent, String child)
                                      也可以使用父路徑和子路徑結(jié)合,實(shí)現(xiàn)代表文件路徑,例如:
                                               File f4 = new File(“d:\\test\\”,”1.txt”);
                                      這樣代表的文件路徑是:d:\test\1.txt。
                   2、File類常用方法
          File類中包含了很多獲得文件或文件夾屬性的方法,使用起來(lái)比較方便,下面將常見的方法介紹如下:
                             a、createNewFile方法
                                               public boolean createNewFile() throws IOException
          該方法的作用是創(chuàng)建指定的文件。該方法只能用于創(chuàng)建文件,不能用于創(chuàng)建文件夾,且文件路徑中包含的文件夾必須存在。
                             b、delect方法
                                               public boolean delete()
          該方法的作用是刪除當(dāng)前文件或文件夾。如果刪除的是文件夾,則該文件夾必須為空。如果需要?jiǎng)h除一個(gè)非空的文件夾,則需要首先刪除該文件夾內(nèi)部的每個(gè)文件和文件夾,然后在可以刪除,這個(gè)需要書寫一定的邏輯代碼實(shí)現(xiàn)。
                             c、exists方法
                                               public boolean exists()
                                      該方法的作用是判斷當(dāng)前文件或文件夾是否存在。
                             d、getAbsolutePath方法
                                               public String getAbsolutePath()
          該方法的作用是獲得當(dāng)前文件或文件夾的絕對(duì)路徑。例如c:\test\1.t則返回c:\test\1.t。
                             e、getName方法
                                               public String getName()
                                      該方法的作用是獲得當(dāng)前文件或文件夾的名稱。例如c:\test\1.t,則返回1.t。
                             f、getParent方法
                                               public String getParent()
                                      該方法的作用是獲得當(dāng)前路徑中的父路徑。例如c:\test\1.t則返回c:\test。
                             g、isDirectory方法
                                               public boolean isDirectory()
                                      該方法的作用是判斷當(dāng)前File對(duì)象是否是目錄。
                             h、isFile方法
                                               public boolean isFile()
                                      該方法的作用是判斷當(dāng)前File對(duì)象是否是文件。
                             i、length方法
                                               public long length()
          該方法的作用是返回文件存儲(chǔ)時(shí)占用的字節(jié)數(shù)。該數(shù)值獲得的是文件的實(shí)際大小,而不是文件在存儲(chǔ)時(shí)占用的空間數(shù)。
                             j、list方法
                                               public String[] list()
          該方法的作用是返回當(dāng)前文件夾下所有的文件名和文件夾名稱。說(shuō)明,該名稱不是絕對(duì)路徑。
                             k、listFiles方法
                                               public File[] listFiles()
                                      該方法的作用是返回當(dāng)前文件夾下所有的文件對(duì)象。
                             l、mkdir方法
                                               public boolean mkdir()
          該方法的作用是創(chuàng)建當(dāng)前文件文件夾,而不創(chuàng)建該路徑中的其它文件夾。假設(shè)d盤下只有一個(gè)test文件夾,則創(chuàng)建d:\test\abc文件夾則成功,如果創(chuàng)建d:\a\b文件夾則創(chuàng)建失敗,因?yàn)樵撀窂街衐:\a文件夾不存在。如果創(chuàng)建成功則返回true,否則返回false。
                             m、mkdirs方法
                                               public boolean mkdirs()
          該方法的作用是創(chuàng)建文件夾,如果當(dāng)前路徑中包含的父目錄不存在時(shí),也會(huì)自動(dòng)根據(jù)需要?jiǎng)?chuàng)建。
                             n、renameTo方法
                                               public boolean renameTo(File dest)
          該方法的作用是修改文件名。在修改文件名時(shí)不能改變文件路徑,如果該路徑下已有該文件,則會(huì)修改失敗。
                             o、setReadOnly方法
                                               public boolean setReadOnly()
                                      該方法的作用是設(shè)置當(dāng)前文件或文件夾為只讀。
                   3、File類基本示例
                             以上各方法實(shí)現(xiàn)的測(cè)試代碼如下:
                                      import java.io.File;
          /**
           * File類使用示例
           */
          public class FileDemo {
                   public static void main(String[] args) {
                             //創(chuàng)建File對(duì)象
                             File f1 = new File("d:\\test");
                             File f2 = new File("1.txt");
                             File f3 = new File("e:\\file.txt");
                             File f4 = new File("d:\\","1.txt");
                             //創(chuàng)建文件
                             try{
                                      boolean b = f3.createNewFile();
                             }catch(Exception e){
                                      e.printStackTrace();
                             }
                             //判斷文件是否存在
                             System.out.println(f4.exists());
                             //獲得文件的絕對(duì)路徑
                             System.out.println(f3.getAbsolutePath());
                             //獲得文件名
                             System.out.println(f3.getName());
                             //獲得父路徑
                             System.out.println(f3.getParent());
                             //判斷是否是目錄
                             System.out.println(f1.isDirectory());
                             //判斷是否是文件
                             System.out.println(f3.isFile());
                             //獲得文件長(zhǎng)度
                             System.out.println(f3.length());
                             //獲得當(dāng)前文件夾下所有文件和文件夾名稱
                             String[] s = f1.list();
                             for(int i = 0;i < s.length;i++){
                                      System.out.println(s[i]);
                             }
                             //獲得文件對(duì)象
                             File[] f5 = f1.listFiles();
                             for(int i = 0;i < f5.length;i++){
                                      System.out.println(f5[i]);
                             }
                             //創(chuàng)建文件夾
                             File f6 = new File("e:\\test\\abc");
                             boolean b1 = f6.mkdir();
                             System.out.println(b1);
                             b1 = f6.mkdirs();
                             System.out.println(b1);
                             //修改文件名
                             File f7 = new File("e:\\a.txt");
                             boolean b2 = f3.renameTo(f7);
                             System.out.println(b2);
                             //設(shè)置文件為只讀
                             f7.setReadOnly();             
                   }
          }
                   4、File類綜合示例
          下面以兩個(gè)示例演示File類的綜合使用。第一個(gè)示例是顯示某個(gè)文件夾下的所有文件和文件夾,原理是輸出當(dāng)前名稱,然后判斷當(dāng)前File對(duì) 象是文件還是文件夾,如果則獲得該文件夾下的所有子文件和子文件夾,并遞歸調(diào)用該方法實(shí)現(xiàn)。第二個(gè)示例是刪除某個(gè)文件夾下的所有文件和文件夾,原理是判斷 是否是文件,如果是文件則直接刪除,如果是文件夾,則獲得該文件夾下所有的子文件和子文件夾,然后遞歸調(diào)用該方法處理所有子文件和子文件夾,然后將空文件 夾刪除。則測(cè)試時(shí)謹(jǐn)慎使用第二個(gè)方法,以免刪除自己有用的數(shù)據(jù)文件。示例代碼如下:
                                      import java.io.File;
          /**
           * 文件綜合使用示例
           */
          public class AdvanceFileDemo {
                   public static void main(String[] args) {
                             File f = new File("e:\\Book");
                             printAllFile(f);
                             File f1 = new File("e:\\test");
                             deleteAll(f1);
                   }
                  
                   /**
                    * 打印f路徑下所有的文件和文件夾
                    * @param f 文件對(duì)象
                    */
                   public static void printAllFile(File f){
                             //打印當(dāng)前文件名
                             System.out.println(f.getName());
                             //是否是文件夾
                             if(f.isDirectory()){
                                      //獲得該文件夾下所有子文件和子文件夾
                                      File[] f1 = f.listFiles();
                                      //循環(huán)處理每個(gè)對(duì)象
                                      int len = f1.length;
                                      for(int i = 0;i < len;i++){
                                               //遞歸調(diào)用,處理每個(gè)文件對(duì)象
                                               printAllFile(f1[i]);
                                      }
                             }
                   }
                  
                   /**
                    * 刪除對(duì)象f下的所有文件和文件夾
                    * @param f 文件路徑
                    */
                   public static void deleteAll(File f){
                             //文件
                             if(f.isFile()){
                                      f.delete();
                             }else{ //文件夾
                                      //獲得當(dāng)前文件夾下的所有子文件和子文件夾
                                      File f1[] = f.listFiles();
                                      //循環(huán)處理每個(gè)對(duì)象
                                      int len = f1.length;
                                      for(int i = 0;i < len;i++){
                                               //遞歸調(diào)用,處理每個(gè)文件對(duì)象
                                               deleteAll(f1[i]);
                                      }
                                      //刪除當(dāng)前文件夾
                                      f.delete();
                             }
                   }
          }
                   關(guān)于File類的使用就介紹這么多,其它的方法和使用時(shí)需要注意的問(wèn)題還需要多進(jìn)行練習(xí)和實(shí)際使用。
          11.3.1.3 讀取文件
                   雖然前面介紹了流的概念,但是這個(gè)概念對(duì)于初學(xué)者來(lái)說(shuō),還是比較抽象的,下面以實(shí)際的讀取文件為例子,介紹流的概念,以及輸入流的基本使用。
                   按照前面介紹的知識(shí),將文件中的數(shù)據(jù)讀入程序,是將程序外部的數(shù)據(jù)傳入程序中,應(yīng)該使用輸入流——InputStream或Reader。而由于讀取的是特定的數(shù)據(jù)源——文件,則可以使用輸入對(duì)應(yīng)的子類FileInputStream或FileReader實(shí)現(xiàn)。
                   在實(shí)際書寫代碼時(shí),需要首先熟悉讀取文件在程序中實(shí)現(xiàn)的過(guò)程。在Java語(yǔ)言的IO編程中,讀取文件是分兩個(gè)步驟:1、將文件中的數(shù)據(jù)轉(zhuǎn)換為流,2、讀取流內(nèi)部的數(shù)據(jù)。其中第一個(gè)步驟由系統(tǒng)完成,只需要?jiǎng)?chuàng)建對(duì)應(yīng)的流對(duì)象即可,對(duì)象創(chuàng)建完成以后步驟1就完成了,第二個(gè)步驟使用輸入流對(duì)象中的read方法即可實(shí)現(xiàn)了。
                   使用輸入流進(jìn)行編程時(shí),代碼一般分為3個(gè)部分:1、創(chuàng)建流對(duì)象,2、讀取流對(duì)象內(nèi)部的數(shù)據(jù),3、關(guān)閉流對(duì)象。下面以讀取文件的代碼示例:
                             import java.io.*;
          /**
           * 使用FileInputStream讀取文件
           */
          public class ReadFile1 {
                   public static void main(String[] args) {
                             //聲明流對(duì)象
                             FileInputStream fis = null;                 
                             try{
                                      //創(chuàng)建流對(duì)象
                                      fis = new FileInputStream("e:\\a.txt");
                                      //讀取數(shù)據(jù),并將讀取到的數(shù)據(jù)存儲(chǔ)到數(shù)組中
                                      byte[] data = new byte[1024]; //數(shù)據(jù)存儲(chǔ)的數(shù)組
                                      int i = 0; //當(dāng)前下標(biāo)
                                      //讀取流中的第一個(gè)字節(jié)數(shù)據(jù)
                                      int n = fis.read();
                                      //依次讀取后續(xù)的數(shù)據(jù)
                                      while(n != -1){ //未到達(dá)流的末尾
                                               //將有效數(shù)據(jù)存儲(chǔ)到數(shù)組中
                                               data[i] = (byte)n;
                                               //下標(biāo)增加
                                               i++;
                                               //讀取下一個(gè)字節(jié)的數(shù)據(jù)
                                                n = fis.read();
                                      }
                                     
                                      //解析數(shù)據(jù)
                                      String s = new String(data,0,i);
                                      //輸出字符串
                                      System.out.println(s);
                             }catch(Exception e){
                                      e.printStackTrace();
                             }finally{
                                      try{
                                               //關(guān)閉流,釋放資源
                                               fis.close();
                                      }catch(Exception e){}
                             }
                   }
          }
                   在該示例代碼中,首先創(chuàng)建一個(gè)FileInputStream類型的對(duì)象fis:
                             fis = new FileInputStream("e:\\a.txt");
                   這樣建立了一個(gè)連接到數(shù)據(jù)源e:\a.txt的流,并將該數(shù)據(jù)源中的數(shù)據(jù)轉(zhuǎn)換為流對(duì)象fis,以后程序讀取數(shù)據(jù)源中的數(shù)據(jù),只需要從流對(duì)象fis中讀取即可。
                   讀取流fis中的數(shù)據(jù),需要使用read方法,該方法是從InputStream類中繼承過(guò)來(lái)的方法,該方法的作用是每次讀取流中的一個(gè)字節(jié),如果需要讀取流中的所有數(shù)據(jù),需要使用循環(huán)讀取,當(dāng)?shù)竭_(dá)流的末尾時(shí),read方法的返回值是-1。
                   在該示例中,首先讀取流中的第一個(gè)字節(jié):
                             int n = fis.read();
                   并將讀取的值賦值給int值n,如果流fis為空,則n的值是-1,否則n中的最后一個(gè)字節(jié)包含的時(shí)流fis中的第一個(gè)字節(jié),該字節(jié)被讀取以后,將被從流fis中刪除。
                   然后循環(huán)讀取流中的其它數(shù)據(jù),如果讀取到的數(shù)據(jù)不是-1,則將已經(jīng)讀取到的數(shù)據(jù)n強(qiáng)制轉(zhuǎn)換為byte,即取n中的有效數(shù)據(jù)——最后一個(gè)字節(jié),并存儲(chǔ)到數(shù)組data中,然后調(diào)用流對(duì)象fis中的read方法繼續(xù)讀取流中的下一個(gè)字節(jié)的數(shù)據(jù)。一直這樣循環(huán)下去,直到讀取到的數(shù)據(jù)是-1,也就是讀取到流的末尾則循環(huán)結(jié)束。
                   這里的數(shù)組長(zhǎng)度是1024,所以要求流中的數(shù)據(jù)長(zhǎng)度不能超過(guò)1024,所以該示例代碼在這里具有一定的局限性。如果流的數(shù)據(jù)個(gè)數(shù)比較多,則可以將1024擴(kuò)大到合適的個(gè)數(shù)即可。
                   經(jīng)過(guò)上面的循環(huán)以后,就可以將流中的數(shù)據(jù)依次存儲(chǔ)到data數(shù)組中,存儲(chǔ)到data數(shù)組中有效數(shù)據(jù)的個(gè)數(shù)是i個(gè),即循環(huán)次數(shù)。
                   其實(shí)截至到這里,IO操作中的讀取數(shù)據(jù)已經(jīng)完成,然后再按照數(shù)據(jù)源中的數(shù)據(jù)格式,這里是文件的格式,解析讀取出的byte數(shù)組即可。
                   該示例代碼中的解析,只是將從流對(duì)象中讀取到的有效的數(shù)據(jù),也就是data數(shù)組中的前n個(gè)數(shù)據(jù),轉(zhuǎn)換為字符串,然后進(jìn)行輸出。
                   在該示例代碼中,只是在catch語(yǔ)句中輸出異常的信息,便于代碼的調(diào)試,在實(shí)際的程序中,需要根據(jù)情況進(jìn)行一定的邏輯處理,例如給出提示信息等。
                   最后在finally語(yǔ)句塊中,關(guān)閉流對(duì)象fis,釋放流對(duì)象占用的資源,關(guān)閉數(shù)據(jù)源,實(shí)現(xiàn)流操作的結(jié)束工作。
                   上面詳細(xì)介紹了讀取文件的過(guò)程,其實(shí)在實(shí)際讀取流數(shù)據(jù)時(shí),還可以使用其它的read方法,下面的示例代碼是使用另外一個(gè)read方法實(shí)現(xiàn)讀取的代碼:
                             import java.io.FileInputStream;
          /**
           * 使用FileInputStream讀取文件
           */
          public class ReadFile2 {
                   public static void main(String[] args) {
                             //聲明流對(duì)象
                             FileInputStream fis = null;                 
                             try{
                                      //創(chuàng)建流對(duì)象
                                      fis = new FileInputStream("e:\\a.txt");
                                      //讀取數(shù)據(jù),并將讀取到的數(shù)據(jù)存儲(chǔ)到數(shù)組中
                                      byte[] data = new byte[1024]; //數(shù)據(jù)存儲(chǔ)的數(shù)組
                                      int i = fis.read(data);
                                     
                                      //解析數(shù)據(jù)
                                      String s = new String(data,0,i);
                                      //輸出字符串
                                      System.out.println(s);
                             }catch(Exception e){
                                      e.printStackTrace();
                             }finally{
                                      try{
                                               //關(guān)閉流,釋放資源
                                               fis.close();
                                      }catch(Exception e){}
                             }
                   }
          }
                   該示例代碼中,只使用一行代碼:
                             int i = fis.read(data);
                   就實(shí)現(xiàn)了將流對(duì)象fis中的數(shù)據(jù)讀取到字節(jié)數(shù)組data中。該行代碼的作用是將fis流中的數(shù)據(jù)讀取出來(lái),并依次存儲(chǔ)到數(shù)組data中,返回值為實(shí)際讀取的有效數(shù)據(jù)的個(gè)數(shù)。
                   使用該中方式在進(jìn)行讀取時(shí),可以簡(jiǎn)化讀取的代碼。
                   當(dāng)然,在讀取文件時(shí),也可以使用Reader類的子類FileReader進(jìn)行實(shí)現(xiàn),在編寫代碼時(shí),只需要將上面示例代碼中的byte數(shù)組替換成char數(shù)組即可。
          使用FileReader讀取文件時(shí),是按照char為單位進(jìn)行讀取的,所以更適合于文本文件的讀取,而對(duì)于二進(jìn)制文件或自定義格式的文件來(lái)說(shuō),還是使用FileInputStream進(jìn)行讀取,方便對(duì)于讀取到的數(shù)據(jù)進(jìn)行解析和操作。
          讀取其它數(shù)據(jù)源的操作和讀取文件類似,最大的區(qū)別在于建立流對(duì)象時(shí)選擇的類不同,而流對(duì)象一旦建立,則基本的讀取方法是一樣,如果只使用最基本的read方法進(jìn)行讀取,則使用基本上是一致的。這也是IO類設(shè)計(jì)的初衷,使得對(duì)于流對(duì)象的操作保持一致,簡(jiǎn)化IO類使用的難度。
           程。
                   基本的輸出流包含OutputStream和Writer兩個(gè),區(qū)別是OutputStream體系中的類(也就是OutputStream的子類)是按照字節(jié)寫入的,而Writer體系中的類(也就是Writer的子類)是按照字符寫入的。
                   使用輸出流進(jìn)行編程的步驟是:
                             1、建立輸出流
                                      建立對(duì)應(yīng)的輸出流對(duì)象,也就是完成由流對(duì)象到外部數(shù)據(jù)源之間的轉(zhuǎn)換。
                             2、向流中寫入數(shù)據(jù)
                                      將需要輸出的數(shù)據(jù),調(diào)用對(duì)應(yīng)的write方法寫入到流對(duì)象中。
                             3、關(guān)閉輸出流
                                      在寫入完畢以后,調(diào)用流對(duì)象的close方法關(guān)閉輸出流,釋放資源。
                   在使用輸出流向外部輸出數(shù)據(jù)時(shí),程序員只需要將數(shù)據(jù)寫入流對(duì)象即可,底層的API實(shí)現(xiàn)將流對(duì)象中的內(nèi)容寫入外部數(shù)據(jù)源,這個(gè)寫入的過(guò)程對(duì)于程序員來(lái)說(shuō)是透明的,不需要專門書寫代碼實(shí)現(xiàn)。
                   在向文件中輸出數(shù)據(jù),也就是寫文件時(shí),使用對(duì)應(yīng)的文件輸出流,包括FileOutputStream和FileWriter兩個(gè)類,下面以FileOutputStream為例子說(shuō)明輸出流的使用。示例代碼如下:
                             import java.io.*;
          /**
           * 使用FileOutputStream寫文件示例
           */
          public class WriteFile1 {
                   public static void main(String[] args) {
                             String s = "Java語(yǔ)言";
                             int n = 100;
                             //聲明流對(duì)象
                             FileOutputStream fos = null;
                             try{
                                      //創(chuàng)建流對(duì)象
                                      fos = new FileOutputStream("e:\\out.txt");
                                      //轉(zhuǎn)換為byte數(shù)組
                                      byte[] b1 = s.getBytes();
                                      //換行符
                                      byte[] b2 = "\r\n".getBytes();
                                      byte[] b3 = String.valueOf(n).getBytes();
                                      //依次寫入文件
                                      fos.write(b1);
                                      fos.write(b2);
                                      fos.write(b3);
                             } catch (Exception e) {
                                      e.printStackTrace();
                             }finally{
                                      try{
                                               fos.close();
                                      }catch(Exception e){}
                             }
                   }
          }
                   該示例代碼寫入的文件使用記事本打開以后,內(nèi)容為:
                             Java語(yǔ)言
          100
                   在該示例代碼中,演示了將一個(gè)字符串和一個(gè)int類型的值依次寫入到同一個(gè)文件中。在寫入文件時(shí),首先創(chuàng)建了一個(gè)文件輸出流對(duì)象fos:
                             fos = new FileOutputStream("e:\\out.txt");
                   該對(duì)象創(chuàng)建以后,就實(shí)現(xiàn)了從流到外部數(shù)據(jù)源e:\out.txt的連接。說(shuō)明:當(dāng)外部文件不存在時(shí),系統(tǒng)會(huì)自動(dòng)創(chuàng)建該文件,但是如果文件路徑中包含未創(chuàng)建的目錄時(shí)將出現(xiàn)異常。這里書寫的文件路徑可以是絕對(duì)路徑也可以是相對(duì)路徑。
                   在 實(shí)際寫入文件時(shí),有兩種寫入文件的方式:覆蓋和追加。其中“覆蓋”是指清除原文件的內(nèi)容,寫入新的內(nèi)容,默認(rèn)采用該種形式寫文件,“追加”是指在已有文件 的末尾寫入內(nèi)容,保留原來(lái)的文件內(nèi)容,例如寫日志文件時(shí),一般采用追加。在實(shí)際使用時(shí)可以根據(jù)需要采用適合的形式,可以使用:
                             public FileOutputStream(String name, boolean append) throws FileNotFoundException
                   只需要使用該構(gòu)造方法在構(gòu)造FileOutputStream對(duì)象時(shí),將第二個(gè)參數(shù)append的值設(shè)置為true即可。
                   流對(duì)象創(chuàng)建完成以后,就可以使用OutputStream中提供的wirte方法向流中依次寫入數(shù)據(jù)了。最基本的寫入方法只支持byte數(shù)組格式的數(shù)據(jù),所以如果需要將內(nèi)容寫入文件,則需要把對(duì)應(yīng)的內(nèi)容首先轉(zhuǎn)換為byte數(shù)組。
                   這里以如下格式寫入數(shù)據(jù):首先寫入字符串s,使用String類的getBytes方法將該字符串轉(zhuǎn)換為byte數(shù)組,然后寫入字符串“\r\n”,轉(zhuǎn)換方式同上,該字符串的作用是實(shí)現(xiàn)文本文件的換行顯示,最后寫入int數(shù)據(jù)n,首先將n轉(zhuǎn)換為字符串,再轉(zhuǎn)換為byte數(shù)組。這種寫入數(shù)據(jù)的順序以及轉(zhuǎn)換為byte數(shù)組的方式就是流的數(shù)據(jù)格式,也就是該文件的格式。因?yàn)檫@里寫的都是文本文件,所以寫入的內(nèi)容以明文的形式顯示出來(lái),也可以根據(jù)自己需要存儲(chǔ)的數(shù)據(jù)設(shè)定特定的文件格式。
                   其實(shí),所有的數(shù)據(jù)文件,包括圖片文件、聲音文件等等,都是以一定的數(shù)據(jù)格式存儲(chǔ)數(shù)據(jù)的,在保存該文件時(shí),將需要保存的數(shù)據(jù)按照該文件的數(shù)據(jù)格式依次寫入即可,而在打開該文件時(shí),將讀取到的數(shù)據(jù)按照該文件的格式解析成對(duì)應(yīng)的邏輯即可。
                   最后,在數(shù)據(jù)寫入到流內(nèi)部以后,如果需要立即將寫入流內(nèi)部的數(shù)據(jù)強(qiáng)制輸出到外部的數(shù)據(jù)源,則可以使用流對(duì)象的flush方法實(shí)現(xiàn)。如果不需要強(qiáng)制輸出,則只需要在寫入結(jié)束以后,關(guān)閉流對(duì)象即可。在關(guān)閉流對(duì)象時(shí),系統(tǒng)首先將流中未輸出到數(shù)據(jù)源中的數(shù)據(jù)強(qiáng)制輸出,然后再釋放該流對(duì)象占用的內(nèi)存空間。
                   使用FileWriter寫入文件時(shí),步驟和創(chuàng)建流對(duì)象的操作都和該示例代碼一致,只是在轉(zhuǎn)換數(shù)據(jù)時(shí),需要將寫入的數(shù)據(jù)轉(zhuǎn)換為char數(shù)組,對(duì)于字符串來(lái)說(shuō),可以使用String中的toCharArray方法實(shí)現(xiàn)轉(zhuǎn)換,然后按照文件格式寫入數(shù)據(jù)即可。
                   對(duì)于其它類型的字節(jié)輸出流/字符輸出流來(lái)說(shuō),只是在邏輯上連接不同的數(shù)據(jù)源,在創(chuàng)建對(duì)象的代碼上會(huì)存在一定的不同,但是一旦流對(duì)象創(chuàng)建完成以后,基本的寫入方法都是write方法,也需要首先將需要寫入的數(shù)據(jù)按照一定的格式轉(zhuǎn)換為對(duì)應(yīng)的byte數(shù)組/char數(shù)組,然后依次寫入即可。
                   所以IO類的這種設(shè)計(jì)形式,只需要熟悉該體系中的某一個(gè)類的使用以后,就可以觸類旁通的學(xué)會(huì)其它相同類型的類的使用,從而簡(jiǎn)化程序員的學(xué)習(xí),使得使用時(shí)保持統(tǒng)一。

          posted on 2013-09-17 17:51 不高興 閱讀(546) 評(píng)論(4)  編輯  收藏 所屬分類: Java
          評(píng)論:
          • # re: JAVA的文件操作【轉(zhuǎn)】  http://www.location-mer-bretagne.fr Posted @ 2015-10-15 11:07
            熟悉該體系中的某一個(gè)類的使用以后,就可以觸類旁通的學(xué)會(huì)其它相同類型的類的使用,從而簡(jiǎn)化程序員的學(xué)習(xí),使得使用時(shí)保持統(tǒng)一。  回復(fù)  更多評(píng)論   

          • # re: JAVA的文件操作【轉(zhuǎn)】  http://www.lestribusdu13.fr Posted @ 2015-11-10 17:37
            對(duì)于其它類型的字節(jié)輸出流/字符輸出流來(lái)說(shuō),只是在邏輯上連接不同的數(shù)據(jù)源,在創(chuàng)建對(duì)象的代碼上會(huì)存在一定的不同,但是一旦流對(duì)象創(chuàng)建完成以后,基本的寫入方法都是write方法,也需要首先將需要寫入的數(shù)據(jù)按照一定的格式轉(zhuǎn)換為對(duì)應(yīng)的byte數(shù)組/char數(shù)組,然后依次寫入即可。  回復(fù)  更多評(píng)論   

          • # re: JAVA的文件操作【轉(zhuǎn)】  victoria secret uk Posted @ 2016-01-20 16:10
            無(wú)法避免的場(chǎng)景是你可能不得不使用一種專有的協(xié)議和原有系統(tǒng)交互  回復(fù)  更多評(píng)論   

          • # re: JAVA的文件操作【轉(zhuǎn)】  http://www.pataplouf.fr Posted @ 2016-06-06 09:10
            使得使用時(shí)保持統(tǒng)一  回復(fù)  更多評(píng)論   

           
          Copyright © 不高興 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 昌图县| 桃源县| 淅川县| 景洪市| 桂东县| 宜州市| 沙湾县| 上思县| 宁蒗| 正镶白旗| 临泉县| 甘洛县| 两当县| 万山特区| 和政县| 宽城| 华池县| 图木舒克市| 太原市| 漾濞| 那坡县| 德清县| 永嘉县| 五寨县| 施甸县| 博兴县| 会宁县| 汉中市| 颍上县| 乡城县| 股票| 神农架林区| 浦江县| 浮山县| 青岛市| 禄丰县| 南木林县| 乡宁县| 尤溪县| 南平市| 信丰县|