加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

整理 JAVA中的IO流 (字符流与字节流两个大类)

发布时间:2023-06-16 14:02:53 所属栏目:教程 来源:
导读:java中的io流分为两类,字符和字节:

OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。
Writer和Reader字符流的父类,抽象。
实际上在流的操作中,底层
java中的io流分为两类,字符和字节:

OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。
Writer和Reader字符流的父类,抽象。
实际上在流的操作中,底层与文件进行读写的都是字节流,因为即使是字符流的对象,其最终实现读写的也是用的字节流。
操作文件的字节子类FileOutputStream和FileInputStream。
记住,这里面写出和读入的都是字节。
class  useByteStream
{
       /**
        * 使用文件输出字节流
        *
        */
       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)
              {
              }
       }
       /**
        * 使用文件输入字节流
        */
       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)
              {
              }
       }
};
操作文件的字符子类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();
              }
       }
};
两个转换类,OutputStreamWriter,负责将写入字符流转为字节流,InputStreamReader,负责读取字节流转为字符流。
FileWriter的直接父类是OutputStreamWriter,并非Writer。
FileReader的直接父类是InputStreamReader,并非Reader。
因此,最终写入文件和从文件读出的都是字节流。
以上都是基于文件流操作,接下来是基于内存操作流,如果只是写业务代码应该很少会用到。

内存操作流
ByteArrayInputStream\ByteArrayOutputStream。
class useMemoryStream
{
       /**
        * 使用内存操作流,字节
        */
       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);
       }
};
另外,管道流可以实现两个线程之间的通信。
PipedInputStream 和 PipedOutputStream。
PipedOutputStream通过connect方法与PipedInputStream建立连接,后续PipedOutputStream.write的内容,就会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();
       }
};
以上都是无缓存的,考虑到一般场景下,提高使用性能,最好使用有缓存的字符流:BufferedReader和BufferedWriter。

BufferedReader
只能接受输入为字符流,不能为字节流。所以有时候会使用InputStreamReader来转换字节流给字符流使用。还有BufferedWriter

class useBuffer
{
   public static void testBufferReader()
   {
          BufferedReader buf = null;
          //此处用到了字节流转字符流的类InputStreamReader,这是因为BufferedReader只能接收字符流
          buf = new BufferedReader(new InputStreamReader(system.in));
          String str =null;
          try
          {
                 str = buf.readLine();
          }
          catch(IOException e)
          {
                 e.printstacktrace();
          }
          System.out.println("输出的内容为:"+str);
   }
   public static void testBufferWriter()
   {
          File f = new File(".\\log\\test2.txt");
          try {
                //默认缓冲区大小 8K   可以通过 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();
          }
   }
};
SCanner类,输入数据类。
使用方法和BufferedReader类类似,并且方便验证数据类型。

class useScan
{
   public static void testScan()
   {
          Scanner scan = new Scanner(system.in);
          //以回车作为输入的结束符号,否则默认是空格
          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支持正则表达式。比如 hasNext("^\\d{4}-\\d{2}-\\d{2}$") 就是日期格式yyyy-MM-dd的正则表达式,通过next("^\\d{4}-\\d{2}-\\d{2}$")。

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章