溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

整理 JAVA中的IO流 (字符流和字節(jié)流兩個(gè)大類)

發(fā)布時(shí)間:2020-07-26 12:18:57 來(lái)源:網(wǎng)絡(luò) 閱讀:1123 作者:一杯開(kāi)心茶 欄目:軟件技術(shù)

java中的io流分為兩類,字符和字節(jié):

  • OutputStream和InputStream字節(jié)流的父類,抽象。OutputStream有兩個(gè)提供了實(shí)現(xiàn)的接口closable和flushable。
  • Writer和Reader字符流的父類,抽象。
    實(shí)際上在流的操作中,底層與文件進(jìn)行讀寫(xiě)的都是字節(jié)流,因?yàn)榧词故亲址鞯膶?duì)象,其最終實(shí)現(xiàn)讀寫(xiě)的也是用的字節(jié)流。
  1. 操作文件的字節(jié)子類FileOutputStream和FileInputStream。
    記住,這里面寫(xiě)出和讀入的都是字節(jié)。
class  useByteStream
{
       /**
        * 使用文件輸出字節(jié)流
        *
        */
       public static void testFileOutputStream()
       {
              OutputStream out = null;
              try
              {
                     File f = new File(".\\log\\test.txt");
                     //out = new FileOutputStream(f);
                     out = new FileOutputStream(f,true); //追加方式記錄到文件
                     String str = "Hello World!!!";
                     byte b[] = str.getBytes();
                     out.write(b);
                     out.close();
              }
              catch(FileNotFoundException e)
              {

              }
              catch(IOException e)
              {

              }
       }

       /**
        * 使用文件輸入字節(jié)流
        */
       public static void testFileInputStream()
       {
              InputStream out = null;
              try
              {
                     File f = new File(".\\log\\test.txt");
                     out = new FileInputStream(f);
                     String str = "Hello World!!!";
                     byte b[] = new byte[1000];
                     int len = out.read(b);
                     System.out.println(new String(b,0, len) );
                     out.close();
              }
              catch(FileNotFoundException e)
              {

              }
              catch(IOException e)
              {

              }
       }
};
  1. 操作文件的字符子類FileWriter和FileReader
class useCharStream
{
       /**
        * 使用文件字符輸出流
        */
       public static void testFileWriter()
       {
              Writer w = null;
              try
              {
                     File f = new File(".\\log\\test2.txt");
                     w = new FileWriter(f,true); //追加方式
                     w.write("hello world\r\n");
                     w.close();
              }
              catch(FileNotFoundException e)
              {
                     e.printStackTrace();
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }

       }

       /**
        * 使用文件字符輸入流
        */
       public static void testFileReader()
       {
              Reader w = null;
              try
              {
                     File f = new File(".\\log\\test2.txt");
                     w = new FileReader(f);
                     char c[] = new char[1024];
                     w.read(c);
                     System.out.println(c);
                     w.close();
              }
              catch(FileNotFoundException e)
              {
                     e.printStackTrace();
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }
       }

};
  1. 兩個(gè)轉(zhuǎn)換類,OutputStreamWriter,負(fù)責(zé)將寫(xiě)入字符流轉(zhuǎn)為字節(jié)流,InputStreamReader,負(fù)責(zé)讀取字節(jié)流轉(zhuǎn)為字符流。
    FileWriter的直接父類是OutputStreamWriter,并非Writer。
    FileReader的直接父類是InputStreamReader,并非Reader。
    因此,最終寫(xiě)入文件和從文件讀出的都是字節(jié)流。

    以上都是基于文件流操作,接下來(lái)是基于內(nèi)存操作流,如果只是寫(xiě)業(yè)務(wù)代碼應(yīng)該很少會(huì)用到。

  2. 內(nèi)存操作流
    ByteArrayInputStream\ByteArrayOutputStream。
class useMemoryStream
{
       /**
        * 使用內(nèi)存操作流,字節(jié)
        */
       public static void testByteArray()
       {
              String str = "Hello world";
              ByteArrayInputStream bis = null;
              ByteArrayOutputStream bos = null;

              bis = new ByteArrayInputStream(str.getBytes());
              bos = new ByteArrayOutputStream();
              int temp =0;
              while((temp=bis.read())!=-1)
              {
                     char c = (char)temp;
                     bos.write(Character.toUpperCase(c));
              }
              String newStr = bos.toString();
              try
              {
                     bis.close();
                     bos.close();
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }
              System.out.println(newStr);
       }
};
  1. 另外,管道流可以實(shí)現(xiàn)兩個(gè)線程之間的通信。
    PipedInputStream 和 PipedOutputStream。
    PipedOutputStream通過(guò)connect方法與PipedInputStream建立連接,后續(xù)PipedOutputStream.write的內(nèi)容,就會(huì)PipedInputStream.read方法讀取
class Send implements Runnable
{
       private PipedOutputStream pos  = null;
       public Send()
       {
              this.pos = new PipedOutputStream();
       }
       public void run()
       {
              String str = "Hello world!!!";
              try
              {
                     try
                     {
                           Thread.sleep(2000);
                     }
                     catch(InterruptedException e)
                     {
                           e.printStackTrace();
                     }
                     this.pos.write(str.getBytes());
                     System.out.println("thread:"+Thread.currentThread().getId()+",Send  string:"+str);

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

              try
              {
                     this.pos.close();
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }
       }
       public PipedOutputStream getPos()
       {
              return this.pos;
       }
};
class Receive implements Runnable
{
       private PipedInputStream pis = null;
       public Receive()
       {
              this.pis = new PipedInputStream();
       }
       public void run()
       {
              byte b[] = new byte[1024];
              int len =0;
              try
              {
                     len = this.pis.read(b); //阻塞方式

              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }
              try
              {
                     pis.close();
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }
              System.out.println("thread:"+Thread.currentThread().getId()+",receive:"+new  String(b,0,len));

       }

       public PipedInputStream getPis()
       {
              return this.pis;
       }
};
class pipedTest
{
       public void pipedStream()
       {
              Send s = new Send();
              Receive r = new Receive();
              try {
                     s.getPos().connect(r.getPis());
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }

              new Thread(r).start();

              new Thread(s).start();

       }
};

以上都是無(wú)緩存的,考慮到一般場(chǎng)景下,提高使用性能,最好使用有緩存的字符流:BufferedReader和BufferedWriter。

  1. BufferedReader
    只能接受輸入為字符流,不能為字節(jié)流。所以有時(shí)候會(huì)使用InputStreamReader來(lái)轉(zhuǎn)換字節(jié)流給字符流使用。還有BufferedWriter

    class useBuffer
    {
       public static void testBufferReader()
       {
              BufferedReader buf = null;
              //此處用到了字節(jié)流轉(zhuǎn)字符流的類InputStreamReader,這是因?yàn)锽ufferedReader只能接收字符流
              buf = new BufferedReader(new InputStreamReader(System.in));
              String str =null;
              try
              {
                     str = buf.readLine();
              }
              catch(IOException e)
              {
                     e.printStackTrace();
              }
              System.out.println("輸出的內(nèi)容為:"+str);
    
       }
       public static void testBufferWriter()
       {
              File f = new File(".\\log\\test2.txt");
              try {
                    //默認(rèn)緩沖區(qū)大小 8K   可以通過(guò) new BufferedWriter(new FileWriter(f),1024);指定大小為1K
                     BufferedWriter out =new BufferedWriter(new FileWriter(f));
                     out.write("123321123355555", 0, 10);
                      out.write("\r\n");
                      out.close();
              } catch (IOException e) {
                     e.printStackTrace();
              }
       }
    };
  2. SCanner類,輸入數(shù)據(jù)類。
    使用方法和BufferedReader類類似,并且方便驗(yàn)證數(shù)據(jù)類型。

    class useScan
    {
       public static void testScan()
       {
              Scanner scan = new Scanner(System.in);
              //以回車作為輸入的結(jié)束符號(hào),否則默認(rèn)是空格
              scan.useDelimiter("\r\n");
              if(scan.hasNextInt()==true)
              {
                     int str = scan.nextInt();
                     System.out.println("int "+str);
              }
              else
              {
                     String str = scan.next();
                     System.out.println("string "+str);
              }
    
       }
    };

    scan.hasNext支持正則表達(dá)式。比如 hasNext("^\\d{4}-\\d{2}-\\d{2}$") 就是日期格式y(tǒng)yyy-MM-dd的正則表達(dá)式,通過(guò)next("^\\d{4}-\\d{2}-\\d{2}$")。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI