<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Java 輸入輸出流 [TOC] ## 導學 Java的輸入輸出流在我們的日常的使用中,無處不在。只要涉及到數據的傳輸,比如復制粘貼文件,微信,QQ上傳頭像,下載游戲安裝包等都是在利用輸入輸出流。再比如我們之前所學習過的`System.out.println()`,它的作用就是向控制臺輸出一條信息,也是運用了流的概念。 **那么什么是流呢?** >[info]**流就是指一連串流動的字符,以先進先出的的方式發送信息的通道** ![](https://img.kancloud.cn/b0/f3/b0f39e57f50e5d03b438f1b131ae836a_828x169.png) 在程序中所有的數據都是以流的方式進行傳輸或保存的,程序需要數據的時候要使用輸入流讀取數據,而當程序需要將一些數據保存起來的時候,就要使用輸出流完成。 **程序中的輸入輸出都是以流的形式保存的,流中保存的實際上全都是字節文件**。 **什么是輸入輸出流** * 流是個抽象的概念,是對輸入輸出設備的抽象,輸入流可以看作一個輸入通道,輸出流可以看作一個輸出通道。 * 輸入流是相對程序而言的,外部傳入數據給程序需要借助輸入流。 * 輸出流是相對程序而言的,程序把數據傳輸到外部需要借助輸出流。 在java.io包中操作文件內容的主要有兩大類:字節流(二進制數據)、字符流(char和String等類型的文字數據),兩類都分為輸入和輸出操作。在字節流中輸出數據主要是使用OutputStream完成,輸入使的是InputStream,在字符流中輸出主要是使用Writer類完成,輸入流主要使用Reader類完成。 ## File類應用 ### 文件簡介 首先,什么是文件?**文件可認為是相關記錄或放在一起的數據的集合。** 在實際的存儲數據中,如果對數據的讀寫速度要求不高,而且存儲的數據量也不是很大,此時,可以選擇使用文件這種持久化的存儲方式。 所謂**持久化**,就是當程序退出,或者計算機關機以后,數據還是存在的。但是在程序內存中的數據會在程序關閉或計算機退出時丟失。 文件的組成:路徑+文件的全名(文件名和文件后綴)。 關于文件后綴:只是定義了文件的打開方式不一樣,如果更改后綴不會對文件的內部數據產生變化。 在不同的操作系統中,文件的路徑表示形式是不一樣的。 比如: `windows c:\windows\system\driver.txt` `Linux /user/my/tomcat/startup.txt` >[success] 如果程序需要在不同的操作系統中運行,那么如果出現文件路徑相關的設置時,必須要進行操作系統的判斷,特別是windows和Linux關于斜杠的區別。 >[warning] 針對于不同操作系統的斜杠我們可以使用File類的路徑分隔符常量`File.separator` ### File類應用 `java.io.File`類是一個與文件本身操作有關的類,此類可以實現文件創建,刪除,重命名,取得文件大小,修改日期等常見的系統文件操作 **`File`類常用方法:** | 方法 | 描述 | | --- | --- | | canRead() | 文件是否可讀 | | canWrite() | 文件是否可寫 | | exists() | 文件或目錄是否存在 | | getName() | 獲取文件或路徑的名稱 | | isDirectory() | 是否是目錄 | | isFile() | 是否是文件 | | isHidden() | 是否是隱藏文件 | |mkdir()|是否創建單級目錄| |mkdirs()|是否創建多級目錄| **示例:** ~~~ public class FileDemo { public static void main(String[] args) { //創建File對象 //File file1=new File("c:\\dodoke\\io\\score.txt"); //File file1=new File("c:\\dodoke","io\\score.txt");//文件和目錄分成兩個字符串 File file=new File("c:\\dodoke");//File.separator File file1=new File(file,"io\\score.txt"); //判斷是文件還是目錄 System.out.println("是否是目錄:"+file1.isDirectory()); System.out.println("是否是文件:"+file1.isFile()); //創建目錄 File file2=new File("c:\\dodoke\\set\\HashSet"); if(!file2.exists()) { file2.mkdirs(); } //創建文件 if(!file1.exists()) { try { file1.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } } } ~~~ ### 絕對路徑與相對路徑 #### 絕對路徑 **絕對路徑:是指文件在硬盤上真正存在的路徑。(指對站點的根目錄而言某文件的位置)————以web站點為根目錄為參考基礎的目錄路徑,之所以成為絕對,意指當所有網頁引用同一文件時,所引用的路徑都是一樣的。** ##### 引用本地文件 ~~~ Windows系統中的文件絕對路徑 E:\companyWorkSpace\braun\bin\src\main\resources\js\dicList.js 當我們想要引入這樣本地的一個js文件的時候。 寫法: <script src="file:///E:/companyWorkSpace/braun/bin/src/main/resources/js/dicList.js"></script> ~~~ `file:///`:本地超文本傳輸協議 注意點:需要將路徑中的反斜杠\\改為斜桿/ ##### 引用網絡文件 ~~~ 寫法: <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" /> ~~~ `https://`:網絡安全超文本協議 #### 相對路徑 **相對路徑:就是相對于自己的目標文件的位置。(指以當前文件所處目錄而言文件的位置)————以引用文件之間網頁所在位置為參考基礎,而建立出的目錄路徑。因此當保存于不同目錄的網頁引用同一個文件時,所使用的路徑將不相同,故稱之為相對。** ##### 相對路徑的點與斜杠概念 **/、./、../、../../** * `/`這個斜杠代表的是根目錄的意思,什么是根目錄呢? **先看例子:** ~~~ F盤中有個文件夾vue_bamboos和一張圖片 test-me.png vue_bamboos下有一個文件夾 a , a文件夾中有一個文件夾b; b文件夾下有一個index.html文件; F------------------------------------------- vue_bamboos------------------------- a-------------------------- b----------------- index.html- test-me.png------------------------- index.html:顯示一張圖片test-me.png, 這里我們使用就是根目錄,也就是我們項目目錄的上一級,也就是 F 盤是我們的根目錄; 注意,我們的項目目錄是vue_bamboos,但是vue_bamboos不是根目錄,它的上一級才是!!! <body> <img src="/test-me.png" alt="測試根目錄"> </body> ~~~ * `./`這個代表的是當前目錄,也就是和我們的index.html 在同一級上 **先看例子** ~~~ 假設我們的項目目錄: F--------------------------------- vue_bamboos--------------- index.html------ test-me.png----- <body> <img src="./test-me.png" alt="測試當前目錄"> <img src="test-me.png" alt="測試當前目錄"> </body> 也就是說我們可以這樣寫 ./test-me.png 或者省略 ./ 也是可以的, 直接寫 test-me.png ~~~ * `../`?這個代表的意思是返回到上一級目錄;? **先看例子** ~~~ 假設我們的項目目錄: F------------------------------------- vue_bamboos------------------- index.html---------- b------------------------------ test-me.png--- <body> <img src="../b/test-me.png" alt="測試父目錄"> </body> 也就是說我們先找到index.html所在的vue_bamoos這個文件夾,再在vue_bamoos文件夾的上級目錄F盤中,找到b文件夾,最后找到test-me.png ~~~ > 第四個?`../../`? ? ? ? ?這個代表的是返回到上一級,再向上返回一級,返回了兩級; > 第五個?`../../../`? ? ? 這個比上面的多了一級,那么就是向上返回三級了; ##### eclipse中的相對路徑 在eclipse中路徑比較特殊,clipse中java程序的當前工作目錄都是在項目根目錄下的。 ## 字節流 字節流常用于讀取圖像,音頻,視頻之類的二進制字節數據。 ### 字節輸入流`InputStream` `InputStream`是字節輸入流的父類,以下是`Inputstream`的子類結構圖 ![](https://img.kancloud.cn/65/7c/657ca9420478d84add13fe24f4b7b9c7_894x526.png) > [info]常用的輸入流有`FileInputStream`,`ObjectInputStream`,`BufferedInputStream` #### 文件輸入流`FileInputStream` 該類用于從文件系統中的某個文件中獲得輸入字節,用于讀取諸如圖像數據之類的原始字節流。 **常用方法:** | 方法名 | 描述 | | --- | --- | | public int read() | 從輸入流中讀取一個數據字節 | | public int read(byte\[\] b) | 從輸入流中將最多b.length個字節的數據讀入到一個byte數組中 | | public int read(byte\[\] b,int off,int len) | 從此輸入流中將最多`len`個字節的數據讀入一個 byte 數組中。 | | public void close() | 關閉此文件輸入流并釋放與此流有關的所有系統資源。 | >[warningi] 除了第一個方法可以得到讀取到的下一個數據字節,這三個read()方法,如果返回值為-1,則表示已經到達文件末尾。可以用來作為文件是否讀完的一個標志。 ~~~java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputDemo { public static void main(String[] args) { //創建一個FileInputStream對象 try { FileInputStream fis = new FileInputStream("d:"+File.separator + "fileTest" + File.separator + "abcNew.txt"); //********************無參read()方法使用********************** /*int n = fis.read(); System.out.println((char)n);//得到H */ /*int n = fis.read(); while(n != -1) { System.out.println((char)n); n = fis.read(); }*/ //為了提升代碼的簡潔性 /*int n = 0; while((n = fis.read()) != -1) { System.out.println((char)n); }*/ //*******************read(byte[] b)和read(byte[] b,int off,int len)方法的使用***************** /*byte[] b = new byte[100]; fis.read(b); System.out.println(new String(b));*/ byte[] b = new byte[100]; fis.read(b,0,5); System.out.println(new String(b)); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ ### 字節輸出流`OutputStream` `OutputStream`是字節輸出流的父類,以下是`Outputstream`的子類結構圖 ![](https://img.kancloud.cn/59/a4/59a4a42318b59f71300d0cfee52dcfe0_942x412.png) >[success] 常用的輸入流有`FileOutputStream`,`ObjectOutputStream`,`BufferedOutputStream` #### 文件輸出流`FileOutputStream` 該類用來講數據寫入到文件系統的文件中 **常用方法:** | 方法名 | 描述 | | --- | --- | | public void write(int b) | 將指定字節寫入此文件輸出流。 | | public void write(byte\[\] b) | 將`b.length`個字節從指定 byte 數組寫入此文件輸出流中。 | | public void write(byte\[\] b,int off,int len) | 將指定 byte 數組中從偏移量`off`開始的`len`個字節寫入此文件輸出流。 | | public void close() | 關閉此文件輸出流并釋放與此流有關的所有系統資源。 | ~~~java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputDemo { public static void main(String[] args) { String path = "d:"+File.separator + "fileTest" + File.separator + "abcNew.txt"; FileOutputStream fos; FileInputStream fis; try { fos = new FileOutputStream(path,true); fis = new FileInputStream(path); /*fos.write(50); fos.write('e'); //編碼問題導致 System.out.println(fis.read()); System.out.println((char)fis.read());*/ String content = "\nsay Hello World again!"; fos.write(content.getBytes()); fos.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ **文件拷貝** ~~~java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputDemo { public static void main(String[] args) { String path = "d:"+File.separator + "picture" + File.separator + "20170315inHome.jpg"; String copyPath = "d:"+File.separator + "fileTest" + File.separator + "flower.jpg"; FileInputStream fis; FileOutputStream fos; try { //創建輸入流 fis = new FileInputStream(path); File file = new File(copyPath); //判斷文件的父路徑是否存在,如果不存在則新建目錄 if(!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } //創建新文件 file.createNewFile(); //創建輸出流 fos = new FileOutputStream(copyPath); int n = 0; byte[] b = new byte[1024]; while((n = fis.read(b)) != -1) { //一邊讀取輸入流,一邊寫入到新建的文件中去 //fos.write(b); //為了保證最后復制文件和源文件同樣大小 fos.write(b, 0, n); } fos.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ ### 緩沖流 * 緩沖輸入流`BufferedInputStream` * 緩沖輸出流`BufferedOutputStream` 相較于之前直接從硬盤中讀取數據,利用緩沖輸入輸出流,可以從內存中讀取數據,可以極大的提高讀寫速度。 以緩沖輸入流為例,它是不能直接讀取文件系統中的文件的,需要和文件輸入流結合。讀取原理是,文件輸入流首先從文件系統中讀取數據,讀取到數據后不是直接到程序中,而是給緩沖流讀取到字節數組中。輸出流也是一樣。 >[warning] 針對于緩沖輸出流,如果緩沖區已滿,則執行文件寫入操作,如果緩沖區不滿需要先執行`flush()`方法刷新緩沖區。 ~~~java import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class BufferedIODemo { public final static String PATH = "d:"+File.separator + "fileTest" + File.separator + "abcNew.txt"; public static void main(String[] args) { setBufferedIO(); } public static void setBufferedIO() { try { //首先利用文件輸出流,執行文件的寫操作 FileOutputStream fos = new FileOutputStream(PATH); BufferedOutputStream bos = new BufferedOutputStream(fos); //讀操作 FileInputStream fis = new FileInputStream(PATH); BufferedInputStream bis = new BufferedInputStream(fis); //利用緩沖輸出流進行寫操作,需要注意的是此時數據是寫在緩沖區的,如果緩沖未滿,且沒有調用flush()方法,則不會寫入文件 bos.write(50); bos.write('a'); //一般會要求同時寫flush和close bos.flush(); System.out.println(bis.read()); System.out.println((char)bis.read()); fos.close(); //close()方法會釋放有關bos的一切資源,所以調用close()方法,也會執行寫入操作 bos.close(); fis.close(); bis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ ## 字符流 Java提供了字符流便于針對字符串的輸出,尤其是針對中文的數據處理,都會采用字符流的形式。 ### 字符輸入流`Reader` `Reader`是字符輸入流的父類,以下是字符輸入流的結構圖 ![](https://img.kancloud.cn/55/d9/55d903f08d754e7d1308ab41641462ba_944x474.png) >[info] 常用的字符輸入流有`BufferedReader`,`InputStreamReader`,`FileReader` #### 字節字符轉換輸入流 轉換流,可以將一個字節流轉換為字符流,也可以將一個字符流轉換為字節流。 `InputStreamReader`:**將輸入的字節流轉換為字符流輸入形式。** ~~~java public class ReadDemo { public final static String PATH = "d:"+File.separator + "fileTest" + File.separator + "abcNew.txt"; public static void main(String[] args) { FileInputStream fis; InputStreamReader isr; try { fis = new FileInputStream(PATH); //這里其實是一個流的連接 isr = new InputStreamReader(fis); int n = 0; /*while((n = isr.read()) != -1) { System.out.println((char)n); }*/ char[] charArr = new char[15]; while((n = isr.read(charArr)) != -1) { //System.out.println(new String(charArr)); //根據操作系統和字符編碼的不同,可能最后的讀取的效果不經如人意 System.out.println(new String(charArr,0,n)); } fis.close(); isr.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ ### 字符輸出流`Writer` Writer是字符輸出流的父類,以下是字符輸出流的結構圖 ![](https://img.kancloud.cn/10/7d/107d638d78f77e370f1f18a60e98b888_891x444.png) > 常用的字符輸出流有`BufferedWriter`,`InputStreamWriter`,`FileWriter` #### 字節字符轉換輸出流 轉換流,可以將一個字節流轉換為字符流,也可以將一個字符流轉換為字節流。 `OutputStreamWriter`:**可以將輸出的字符流轉換為字節流的輸出形式。** ~~~java public class WriterDemo { public final static String PATH = "d:"+File.separator + "fileTest" + File.separator + "abcNew.txt"; public final static String PATH2 = "d:"+File.separator + "fileTest" + File.separator + "abcNew2.txt"; public static void main(String[] args) { FileInputStream fis; InputStreamReader isr; FileOutputStream fos; OutputStreamWriter ost; try { fis = new FileInputStream(PATH); isr = new InputStreamReader(fis,"UTF-8"); //其實這個文件并沒有但是文件輸出流會幫我們自動創建一個 fos = new FileOutputStream(PATH2); ost = new OutputStreamWriter(fos,"UTF-8"); int n = 0; char[] charArr = new char[13]; while((n = isr.read(charArr)) != -1) { ost.write(charArr, 0, n); ost.flush(); } fis.close(); isr.close(); fos.close(); ost.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ >[success] 讀寫的時候需要保持編碼的一致 ### 字節字符轉換緩沖流 `BufferedReader`和`BufferedWriter` ~~~java public class BufferedRWDemo { public final static String PATH = "d:"+File.separator + "fileTest" + File.separator + "abcNew.txt"; public final static String PATH2 = "d:"+File.separator + "fileTest" + File.separator + "abcNew2.txt"; public static void main(String[] args) { FileInputStream fis; InputStreamReader isr; FileOutputStream fos; OutputStreamWriter ost; try { fis = new FileInputStream(PATH); isr = new InputStreamReader(fis,"UTF-8"); //其實與之前的緩沖輸入輸出流相比,這里出現的是一個三層的連接 BufferedReader br = new BufferedReader(isr); //其實這個文件并沒有但是文件輸出流會幫我們自動創建一個 fos = new FileOutputStream(PATH2); ost = new OutputStreamWriter(fos,"UTF-8"); BufferedWriter bw = new BufferedWriter(ost); int n = 0; char[] charArr = new char[13]; while((n = br.read(charArr)) != -1) { bw.write(charArr, 0, n); bw.flush(); } fis.close(); isr.close(); fos.close(); ost.close(); br.close(); bw.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~ ### 總結 字符流與字節流中的類多種多樣,不可能全部講完,但是各個類的使用大多是大同小異。 在字符流中使用字節流去讀寫文件,其實只是為了模擬網絡文件的讀寫操作。字符流有著自己的讀寫文件的類`FileReader`和`FileWriter` ## 對象序列化與反序列化 針對于對象序列化,我們可以設想這樣一個場景。比如,我們在同別人聊天的過程中,僅僅是把一條信息發送過去了嗎?并不是這樣的,發送的信息中可能包含發送方的ip,接收方的ip,以及端口號,聊天內容,昵稱等等,那么這些信息如果一條一條的發送過去是沒有辦法接收的。 所以,我們可以把這些信息封裝到一個類中,然后把包含這些信息的對象發送過去,然后接收方就可以根據這些信息作出反應。那么在這個場景中如何去發送對象內容,以及如何去解析對象的內容,就可以通過**對象序列化**技術解決。 **對象序列化的實現步驟:** 1. 創建一個類,實現Serializable接口(只有當類實現了Serializable接口才能序列化與反序列化) 2. 創建該類的對象 3. 將對象寫入文件(不一定要寫入文件,也可以寫入網絡中) 4. 從文件讀取對象信息 >[info]對象序列化需要借助兩個類,`ObjectInputStream()`和`ObjectOutputStream()` >[success]序列化:把Java對象轉換為字節序列的過程。反序列化:把字節序列恢復為Java對象的過程。 ~~~ import java.io.Serializable; public class Goods implements Serializable{ private String goodsId; private String goodsName; private double price; public Goods(String goodsId,String goodsName,double price){ this.goodsId=goodsId; this.goodsName=goodsName; this.price=price; } public String getGoodsId() { return goodsId; } public void setGoodsId(String goodsId) { this.goodsId = goodsId; } public String getGoodsName() { return goodsName; } public void setGoodsName(String goodsName) { this.goodsName = goodsName; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "商品信息 [編號:" + goodsId + ", 名稱:" + goodsName + ", 價格:" + price + "]"; } } ~~~ ~~~ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class GoodsTest { public static void main(String[] args) { // 定義Goods類的對象 Goods goods1 = new Goods("gd001", "電腦", 3000); try { FileOutputStream fos = new FileOutputStream("dodoke.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); FileInputStream fis = new FileInputStream("dodoke.txt"); ObjectInputStream ois = new ObjectInputStream(fis); // 將Goods對象信息寫入文件 oos.writeObject(goods1); oos.writeBoolean(true); oos.flush(); // 讀對象信息 try { Goods goods = (Goods) ois.readObject(); System.out.println(goods); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(ois.readBoolean());//讀取的順序要和寫入的順序一致 fos.close(); oos.close(); fis.close(); ois.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看