Java IO 流之字節(jié)流以及字節(jié)流,字符流轉(zhuǎn)換

字節(jié)流

  • InputStream 輸入字節(jié)流
  • OutputStream 輸出字節(jié)流

輸入字節(jié)流----InputStream

InputStream 是所有的輸入字節(jié)流的父類默穴,它是一個(gè)抽象類禁悠。同樣的來(lái)看它的子類。

FileInputStream 繼承自InputStream

構(gòu)造方法:
 //傳一個(gè)文件路徑(字符串)
 public FileInputStream(String var1) throws FileNotFoundException {
        this(var1 != null?new File(var1):null);
    }//如:FileInputStream in=new FileInputStream(String path);

  //傳一個(gè)文件
 public FileInputStream(File var1) throws FileNotFoundException {
    ....
    }//如:FileInputStream in=new FileInputStream(new File(String path));

  //不常用
 public FileInputStream(FileDescriptor var1) {
     ...
    }
主要方法
  • int read();//返回值int,若返回值為-1脯爪,則代表已經(jīng)讀完珊佣,是不是和字符流很像,但每次讀一個(gè)字節(jié)披粟,并打印,如果存在中文咒锻,可能會(huì)亂碼

  • int read(byte[] bytes);//每次讀bytes字節(jié)

代碼演示:

    /**
     * 需求:控制臺(tái)輸出本文件內(nèi)容
     */
    public class Demo {
        //文件地址
        public static final String PATH = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/com/example/Demo1.java";
        //文件名
        public static final String NAME = "copyTest1.java";

        public static void main(String[] args) {
            //  read();//測(cè)試InputStream 的read()方法
            reads();
        }

        /**
         * 測(cè)試read(byte[] bytes)
         * 可以控制字符集
         */
        private static void reads() {
            FileInputStream inputStream = null;
            try {
                inputStream = new FileInputStream(PATH);
                byte[] bytes = new byte[inputStream.available()];//inputStream.available()獲取文件長(zhǎng)度
                //讀取的字節(jié)長(zhǎng)度
                int len = inputStream.read(bytes);//將數(shù)據(jù)一次性讀取到字節(jié)數(shù)組中
                System.out.println("讀取長(zhǎng)度" + len + "\n" + new String(bytes, "utf-8"));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        /**
         * 測(cè)試read()
         * 每次讀一個(gè)字節(jié),并打印,如果存在中文守屉,可能會(huì)亂碼
         */
        private static void read() {
            FileInputStream inputStream = null;
            try {
                inputStream = new FileInputStream(PATH);
                int len = 0;
                while ((len = inputStream.read()) != -1) {
                    System.out.print((char) len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

結(jié)果----read()惑艇,出現(xiàn)了亂碼.

結(jié)果----read(byte[]bytes),設(shè)置了字符集拇泛,沒(méi)出現(xiàn)亂碼.


有沒(méi)有覺(jué)得都差不多.

輸出字節(jié)流----OutputStream

OutputStream 是所有的輸入字節(jié)流的父類滨巴,它是一個(gè)抽象類。同樣的來(lái)看它的子類俺叭。

FileOutStream 繼承自O(shè)utputStream

構(gòu)造方法:
    //是不是和FileWriter很像恭取,第一個(gè)參數(shù)目的是創(chuàng)建一個(gè)向指定 File 對(duì)象表示的文件中寫(xiě)入數(shù)據(jù)的文件輸出流。如果第二個(gè)參數(shù)為 true熄守,則將字節(jié)寫(xiě)入文件末尾處蜈垮,而不是寫(xiě)入文件開(kāi)始處。
    public FileOutputStream(String var1) throws FileNotFoundException {
            ....
        }

    public FileOutputStream(String var1, boolean var2) throws FileNotFoundException {
            .....
        }

    public FileOutputStream(File var1) throws FileNotFoundException {
            this(var1, false);
        }

    public FileOutputStream(File var1, boolean var2) throws FileNotFoundException {
          ......
        }

    public FileOutputStream(FileDescriptor var1) {
          .....
        }
主要方法
  • void write(byte[]bytes);//寫(xiě)字節(jié)數(shù)組

寫(xiě)純文本文件-----案例

  • Config類代碼:(通用案例1裕照,2攒发,3)

      public class Config {
          public static final String PATH="/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/files";
      }
    
  • 主要代碼

             private static final String fileName = "testOutput.java";
         /**
           *
           */
          private static void write() {
              FileOutputStream outputStream = null;
              try {
                  outputStream = new FileOutputStream(Config.PATH + fileName);
                  outputStream.write("你好啊,美女".getBytes());
              } catch (Exception e) {
                  e.printStackTrace();
              }finally {
                           try {
                               outputStream.close();
                           } catch (IOException e) {
                               e.printStackTrace();
                           }
                       }
          }
    
  • 結(jié)果

拷貝純文本文件-----案例(讀晋南,寫(xiě))

  • 代碼

      /**
           * 拷貝本類文件
           */
          private static void copyFile() {
              String copyName = "copy.java";
              String sourcePath = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/com/example/Demo2.java";
    
              FileInputStream inputStream = null;
              FileOutputStream outputStream = null;
    
              try {
                  inputStream = new FileInputStream(sourcePath);
                  outputStream = new FileOutputStream(Config.PATH + copyName);
                  byte[] bytes = new byte[inputStream.available()];
                  inputStream.read(bytes);
                  outputStream.write(bytes);
    
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  try {
                      inputStream.close();
                      outputStream.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
    
  • 結(jié)果


拷貝圖片-----案例(讀惠猿,寫(xiě))

  • 代碼

      /**
         * 拷貝圖片step1.png
         */
        private static void copyPicture() {
            String picSource = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/images/step1.png";
            String copyName = "copyPic.png";
    
            FileInputStream inputStream = null;
            FileOutputStream outputStream = null;
    
            try {
                inputStream = new FileInputStream(picSource);
                outputStream = new FileOutputStream(Config.PATH + copyName);
    
                //定義緩沖區(qū)--字節(jié)數(shù)組
                byte[] bytes=new byte[1024]; //每次最多讀取1K節(jié)字
                int len=-1;  //每次讀取的字節(jié)長(zhǎng)度
    
                while((len=inputStream.read(bytes))!=-1){ //-1代表的是文件結(jié)尾標(biāo)識(shí)
                    outputStream.write(bytes, 0, len);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    inputStream.close();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
  • 結(jié)果


同樣的,字節(jié)流也有帶緩沖的负间,基本都是一樣的偶妖,當(dāng)讀寫(xiě)純文本的時(shí)候優(yōu)先考慮字符流,讀寫(xiě)非純文本的時(shí)候用字節(jié)流政溃。下面我們繼續(xù)看帶緩沖的字節(jié)流趾访,基本一樣。
帶緩沖的字節(jié)流讀寫(xiě)案例(BufferedInputStream 讀玩祟,BufferedOutputStream 寫(xiě))沒(méi)有關(guān)閉的流你們自行關(guān)閉腹缩。
  • Config 類

      public class Config {
          public static final String PATH="/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/files";
      }
    
  • 測(cè)試類

      /**
       * 帶緩沖的字節(jié)流
       * <p>
       * 需求:使用帶緩沖的字節(jié)流拷貝文件
       */
      public class Demo3 {
    
          //純文本源文件路徑
          private static final String txtPath = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/com/example/Demo2.java";
          //拷貝后的純文本文件名
          private static final String txtName = "copy.java";
    
          //圖片源文件路徑
          private static String picPath = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series11/src/main/java/images/step1.png";
          //拷貝后的圖片名
          private static String picName = "copyPic.png";
    
          public static void main(String[] args) {
              //copy(txtPath, txtName);
              copy(picPath, picName);
          }
    
          /**
           * 拷貝文件
           * Config.PATH 是上面提到的
           *
           * @param sourcePath 源路徑
           * @param targetName 文件名
           */
          private static void copy(String sourcePath, String targetName) {
              //申明變量
              FileInputStream inputStream = null;
              BufferedInputStream bufferedInputStream = null;
    
              FileOutputStream outputStream = null;
              BufferedOutputStream bufferedOutputStream = null;
    
              //實(shí)例化變量
              try {
                  inputStream = new FileInputStream(sourcePath);
                  bufferedInputStream = new BufferedInputStream(inputStream);
    
                  outputStream = new FileOutputStream(Config.PATH + targetName);
                  bufferedOutputStream = new BufferedOutputStream(outputStream);
                  byte[] bytes = new byte[2048];//大小可以自己指定屿聋,但不要非常非常大空扎。
                  int len = 0;
                  while ((len = bufferedInputStream.read(bytes)) != -1) {
                      bufferedOutputStream.write(bytes, 0, len);//向緩沖區(qū)中寫(xiě)入指定長(zhǎng)度的數(shù)據(jù)
                      bufferedOutputStream.flush();//將數(shù)據(jù)從內(nèi)存中寫(xiě)入到文件中
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  try {
                      bufferedInputStream.close();//關(guān)閉流(處理流),其中的包裝流會(huì)自動(dòng)關(guān)閉
                      bufferedOutputStream.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
    
          }
      }
    

結(jié)果

都是一樣的润讥。

InputStram 綁定System.in 案例

    public class Demo4 {

        /**
         * 打印從鍵盤(pán)輸入的字母转锈,直到輸入exit結(jié)束程序
         * @param args
         */
        public static void main(String[] args) {
            InputStream inputStream = System.in;
            int num = -1;
            StringBuilder sb = new StringBuilder();
            while (true) {
                try {
                    num = inputStream.read();
                    //判斷字符是否換行
                    if (num == '\n') {
                        String line = sb.toString().trim();//去除兩邊的空格

                        if (line.equalsIgnoreCase("over")) {
                            break;
                        }
                        System.out.println(line); //打印輸入的一行數(shù)據(jù)(字母是大寫(xiě))
                        //重置字符串變量的內(nèi)容
                        sb.delete(0, sb.length());
                    }
                    sb.append((char) num);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

結(jié)果


可是兄弟們,你們看到打印字符串亂碼了嗎楚殿,字節(jié)流不能操作Unicode字符撮慨,由于Java采用16位的Unicode字符,
所以要使用基于字符的輸入輸出操作。所以有了字符流砌溺,以提供直接的字符輸入輸出的支持影涉。而字節(jié)流怎么轉(zhuǎn)成字符流呢,Java為我們提供了兩個(gè)類规伐,InputStreamReader蟹倾,
OutputStreamWriter。作為字節(jié)流和字符流的橋接猖闪,并可以設(shè)置字符編碼.

  • InputStreamReader 構(gòu)造方法

           //來(lái)自源碼
          // 接收一個(gè)字節(jié)流實(shí)例
          public InputStreamReader(InputStream var1) {
              super(var1);
    
              try {
                  this.sd = StreamDecoder.forInputStreamReader(var1, this, (String)null);
              } catch (UnsupportedEncodingException var3) {
                  throw new Error(var3);
              }
          }
           //接受一個(gè)字節(jié)流實(shí)例和一個(gè)String 類型的參數(shù)鲜棠,再深入看代碼可猜測(cè)var2和字符集(charset)有關(guān)系
          public InputStreamReader(InputStream var1, String var2) throws UnsupportedEncodingException {
              super(var1);
              if(var2 == null) {
                  throw new NullPointerException("charsetName");
              } else {
                  this.sd = StreamDecoder.forInputStreamReader(var1, this, var2);
              }
          }
           //同
          public InputStreamReader(InputStream var1, Charset var2) {
              super(var1);
              if(var2 == null) {
                  throw new NullPointerException("charset");
              } else {
                  this.sd = StreamDecoder.forInputStreamReader(var1, this, var2);
              }
          }
           //基本一樣
          public InputStreamReader(InputStream var1, CharsetDecoder var2) {
              super(var1);
              if(var2 == null) {
                  throw new NullPointerException("charset decoder");
              } else {
                  this.sd = StreamDecoder.forInputStreamReader(var1, this, var2);
              }
          }
    
  • OutputStreamWriter 構(gòu)造方法(實(shí)參var2作用同InputStreamReader)

      public OutputStreamWriter(OutputStream var1, String var2) throws UnsupportedEncodingException {
              super(var1);
              if(var2 == null) {
                  throw new NullPointerException("charsetName");
              } else {
                  this.se = StreamEncoder.forOutputStreamWriter(var1, this, var2);
              }
          }
    
          public OutputStreamWriter(OutputStream var1) {
              super(var1);
    
              try {
                  this.se = StreamEncoder.forOutputStreamWriter(var1, this, (String)null);
              } catch (UnsupportedEncodingException var3) {
                  throw new Error(var3);
              }
          }
    
          public OutputStreamWriter(OutputStream var1, Charset var2) {
              super(var1);
              if(var2 == null) {
                  throw new NullPointerException("charset");
              } else {
                  this.se = StreamEncoder.forOutputStreamWriter(var1, this, var2);
              }
          }
    
          public OutputStreamWriter(OutputStream var1, CharsetEncoder var2) {
              super(var1);
              if(var2 == null) {
                  throw new NullPointerException("charset encoder");
              } else {
                  this.se = StreamEncoder.forOutputStreamWriter(var1, this, var2);
              }
          }
    

案例優(yōu)化,接收打印中文字符

    /**
     * 字節(jié)流培慌,字符流轉(zhuǎn)換
     */
    public class Demo5 {
        public static void main(String[] args) {
            //輸入流綁定鍵盤(pán)輸入
            InputStream inputStream = System.in;
            //字符輸入流聲明
            InputStreamReader inputStreamReader = null;
            try {
                //實(shí)例化帶有編碼格式的字符流
                inputStreamReader = new InputStreamReader(inputStream, "utf-8");
                //包裝
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String line = null;
                while (true) {
                    //判斷讀取
                    line = new String(bufferedReader.readLine());
                    if (line.trim().equalsIgnoreCase("exit")) {
                        break;
                    }
                    //打印輸出
                    System.out.println(line);

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

結(jié)果

持續(xù)深入

    /**
     * 需求:接收鍵盤(pán)輸入的內(nèi)容豁陆,并打印到文件里去
     */
    public class Demo6 {

        public static void main(String[] args) {
    //1. 通過(guò)轉(zhuǎn)換流,獲取到讀取鍵盤(pán)的字符輸入流
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String fileName = "copy.txt";//文件名
            //涉及到了System.in,System.out,System.setOut(...),PrintWriter

            //設(shè)置控制輸出的數(shù)據(jù)位置--保存到文件中
            try {
                //File.separator分隔符
                System.setOut(new PrintStream(Config.PATH + File.separator + fileName));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            //2. 通過(guò)轉(zhuǎn)換流吵护,將控制臺(tái)的字節(jié)流轉(zhuǎn)換成緩沖的字符流
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

            //3. 開(kāi)始讀取數(shù)據(jù)
            String line = null;
            while (true) {
                try {
                    line = reader.readLine().trim();
                    if (line.equalsIgnoreCase("exit")) {
                        break;
                    }
                    writer.write(line);
                    writer.newLine();
                    writer.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }

        }

    }

結(jié)果

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盒音,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子馅而,更是在濱河造成了極大的恐慌里逆,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件用爪,死亡現(xiàn)場(chǎng)離奇詭異原押,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)偎血,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)诸衔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人颇玷,你說(shuō)我怎么就攤上這事笨农。” “怎么了帖渠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵谒亦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我空郊,道長(zhǎng)份招,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任狞甚,我火速辦了婚禮锁摔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哼审。我一直安慰自己谐腰,他們只是感情好孕豹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著十气,像睡著了一般励背。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上砸西,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天椅野,我揣著相機(jī)與錄音,去河邊找鬼籍胯。 笑死竟闪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的杖狼。 我是一名探鬼主播炼蛤,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蝶涩!你這毒婦竟也來(lái)了理朋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绿聘,失蹤者是張志新(化名)和其女友劉穎嗽上,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體熄攘,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兽愤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挪圾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浅萧。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖哲思,靈堂內(nèi)的尸體忽然破棺而出洼畅,到底是詐尸還是另有隱情,我是刑警寧澤棚赔,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布帝簇,位于F島的核電站,受9級(jí)特大地震影響靠益,放射性物質(zhì)發(fā)生泄漏丧肴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一捆毫、第九天 我趴在偏房一處隱蔽的房頂上張望闪湾。 院中可真熱鬧冲甘,春花似錦绩卤、人聲如沸途样。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)何暇。三九已至,卻和暖如春凛驮,著一層夾襖步出監(jiān)牢的瞬間裆站,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工黔夭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宏胯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓本姥,卻偏偏與公主長(zhǎng)得像肩袍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婚惫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容