zoukankan      html  css  js  c++  java
  • Java IO 技术之基本流类

    流式IO

    流(Stream)是字节的源或目的。

    01

          两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。

    流的分类

    节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
    过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。

    InputStream

    2

    三个基本的读方法

          abstract int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
          int read(byte[] b) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
          int read(byte[] b, int off, int len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。

    其它方法
          long skip(long n) :在输入流中跳过n个字节,并返回实际跳过的字节数。
          int available() :返回在不发生阻塞的情况下,可读取的字节数。
          void close() :关闭输入流,释放和这个流相关的系统资源。
          void mark(int readlimit) :在输入流的当前位置放置一个标记,如果读取的字节数多于readlimit设置的值,则流忽略这个标记。
          void reset() :返回到上一个标记。
          boolean markSupported() :测试当前流是否支持mark和reset方法。如果支持,返回true,否则返回false。

    OutputStream

    3

    三个基本的写方法
         abstract void write(int b) :往输出流中写入一个字节。
         void write(byte[] b) :往输出流中写入数组b中的所有字节。
         void write(byte[] b, int off, int len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。
    其它方法
         void flush() :刷新输出流,强制缓冲区中的输出字节被写出。
         void close() :关闭输出流,释放和这个流相关的系统资源。

    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    Demo1:在控制台读取键盘输入,然后显示。Ctrl+C结束运行
    -------------------------------------------------------------------------------

    import  java.io. * ;
     
     public   class  StreamDemo   {
      
       public   static   void  main(String[] args)  throws  Exception   {
       int  data;
      
        while  ((data  =  System.in.read())  !=   - 1 )   {
       System.out.write(data);
      } 
     
      } 
      
     }

    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------

    基本的流类

    1、FileInputStream和FileOutputStream

    节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。

    -------------------------------------------------------------------------------
    Demo2:将字符串写入特定文件,注意write方法只接收字符数组。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
       public   class  StreamDemo   {
      
        public   static   void  main(String[] args)  throws  Exception   {
       FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );
     
         /**/ /* 
        * 注意:FileOutputStream的write方法接收字符数组,不能接收String字符串,
       * 所以要用String的getBytes方法生成一个字符数组
         */ 
      fos.write( " http://www.cnblogs.com " .getBytes()); 
      fos.close();
      
      } 
      
     }

    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------

    String的构造方法的API:
    ------------
    Java API:
    ------------
    String
    public String(byte[] bytes,
                  int offset,
                  int length)

    构造一个新的 String,方法是使用指定的字符集解码字节的指定子数组。新的 String 的长度是一个字符集函数,因此不能等于该子数组的长度。

    当给定字节在给定字符集中无效的情况下,该构造方法无指定的行为。当需要进一步控制解码过程时,应使用 CharsetDecoder 类。

    参数:
    bytes - 要解码为字符的字节
    offset - 要解码的首字节的索引
    length - 要解码的字节数
    抛出:
    IndexOutOfBoundsException - 如果 offset 和 length 参数索引字符超出 bytes 数组的范围

    从以下版本开始:
    JDK1.1
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    Demo3:将字符串写入特定文件,注意write方法只接收字符数组。
      然后通过文件输出流读取数据,注意使用String特定的构造方法。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
    public   class  StreamDemo   {
      
        public   static   void  main(String[] args)  throws  Exception   {
      FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );
      
         /**/ /* 
        * 注意:FileOutputStream的write方法接收字符数组,不能接收String字符串,
        * 所以要用String的getBytes方法生成一个字符数组
         */ 
       fos.write( " http://www.cnblogs.com " .getBytes()); 
       fos.close();
       
        //  使用String的这个构造方法:
        //  String(byte[] bytes, int offset, int length) 
        
       FileInputStream fis  =   new  FileInputStream( " 1.txt " );
        byte [] buf  =   new   byte [ 100 ];
        int  len  =  fis.read(buf);
       
        //  使用String的这个构造方法:
        //  String(byte[] bytes, int offset, int length) 
        System.out.println( new  String(buf,  0 , len));
       fis.close();   //  使用完后记得关闭文件流 
      
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:

    -------------------------------------------------------------------------------

    2、BufferedInputStream和BufferedOutputStream

    过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。
       
    ------------
    Java API:
    ------------
    构造方法摘要
    BufferedOutputStream(OutputStream out)
              创建一个新的缓冲输出流,以将数据写入指定的基础输出流。
    BufferedOutputStream(OutputStream out, int size)
              创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。
    -------------------------------------------------------------------------------
    BufferedOutputStream
    public BufferedOutputStream(OutputStream out)
    创建一个新的缓冲输出流,以将数据写入指定的基础输出流。

    参数:
    out - 基础输出流。
    BufferedOutputStream
    public BufferedOutputStream(OutputStream out,
                                int size)
    创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。

    参数:
    out - 基础输出流。
    size - 缓冲区的大小。
    抛出:
    IllegalArgumentException - 如果 size <= 0
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    Demo4:通过一个OutputStream对象来构造一个BufferedOutputStream对象。
      而FileOutputStream类是OutputStream类的子类,所以可以用它来构造。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
       public   class  StreamDemo  {
       
         public   static   void  main(String[] args)  throws  Exception  {
        
        FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );
        BufferedOutputStream bos  =   new  BufferedOutputStream(fos);
        bos.write( " http://www.cnblogs.com " .getBytes());
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:1.txt文件为空。原因:缓冲区没有写满,程序没有向文件写数据。
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    解决方法1:使用flush()方法:
    -------------------------------------------------------------------------------
    Demo4:使用flush()方法,可以使程序立即向文件写数据。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
      public   class  StreamDemo  {
      
         public   static   void  main(String[] args)  throws  Exception  {
        
        FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );
        BufferedOutputStream bos  =   new  BufferedOutputStream(fos);
        bos.write( " http://www.cnblogs.com " .getBytes());
       
       bos.flush();
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:数据被写入相应的文件。
    -------------------------------------------------------------------------------
    解决方法2:使用close()方法:
    -------------------------------------------------------------------------------
    Demo5:使用close()方法,同样可以使程序立即向文件写数据。
    -------------------------------------------------------------------------------

    import  java.io. * ;
       
       public   class  StreamDemo  {
       
         public   static   void  main(String[] args)  throws  Exception  {
        
        FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );
       BufferedOutputStream bos  =   new  BufferedOutputStream(fos);
       bos.write( " http://www.cnblogs.com " .getBytes());
       
       bos.close();
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:数据被写入相应的文件。
    -------------------------------------------------------------------------------

    flush()和close()的区别:
    还要使用流对象,还需要写数据,使用flush(),否则使用close()。

    另外,使用close()将关闭自己的流对象,同时会关闭与之相关的流对象,如FileOutputStream流。

    -------------------------------------------------------------------------------
    Demo6:使用BufferedInputStream流,从文件中读取数据。
      同样要用InputStream流对象或者其子类的对象来构造。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
      public   class  StreamDemo  {
       
         public   static   void  main(String[] args)  throws  Exception  {
        
        FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );
       BufferedOutputStream bos  =   new  BufferedOutputStream(fos);
        bos.write( " http://www.cnblogs.com " .getBytes());
       
       bos.close();
       
       FileInputStream fis  =   new  FileInputStream( " 1.txt " );
       BufferedInputStream bis  =   new  BufferedInputStream(fis);
        byte [] buf  =   new   byte [ 100 ];
        int  len  =  bis.read(buf);
       
        //  使用String的这个构造方法:
        //  String(byte[] bytes, int offset, int length) 
        System.out.println( new  String(buf,  0 , len));
       bis.close();
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:
    -------------------------------------------------------------------------------

    3、DataInputStream和DataOutputStream

    过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。
    ------------
    Java API:
    ------------
    java.io
    类 DataOutputStream
    java.lang.Object
      java.io.OutputStream
          java.io.FilterOutputStream
              java.io.DataOutputStream
    所有已实现的接口:
    Closeable, DataOutput, Flushable
    public class DataOutputStream
    extends FilterOutputStream
    implements DataOutput

    数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。

    从以下版本开始:
    JDK1.0
    -------------------------------------------------------------------------------
    构造方法摘要
    DataOutputStream(OutputStream out)
              创建一个新的数据输出流,将数据写入指定基础输出流。
    -------------------------------------------------------------------------------
    DataOutputStream
    public DataOutputStream(OutputStream out)
    创建一个新的数据输出流,将数据写入指定基础输出流。计数器 written 被设置为零。

    参数:
    out - 基础输出流,将被保存供以后使用。
    -------------------------------------------------------------------------------
    Demo7:使用DataOutputStream流,将基本数据类型以二进制形式写入文件中。
      同样要用InputStream流对象或者其子类的对象来构造,
      这里使用BufferedOutputStream对象来构造。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
      public   class  StreamDemo  {
      
        public   static   void  main(String[] args)  throws  Exception  {
       
       FileOutputStream fos  =   new  FileOutputStream( " dos.txt " );   //  获得写入文件功能 
        BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  //  获得缓冲功能 
        DataOutputStream dos  =   new  DataOutputStream(bos);   //  获得写入基本类型功能 
        
         /* 
        * 定义8种基本类型的对象
         */ 
        byte  b  =   3 ;
        short  s  =   4 ;
        int  i  =   78 ;
        long  l  =   100000 ; 
        char  ch  =   ' a ' ;
        boolean  bl  =   false ;
        float  f  =   4.5f ;
        double  d  =   4.0001 ;
       
         /* 
        * 将8种基本类型的对象写入文件中
         */ 
       dos.writeByte(b);
       dos.writeShort(s);
       dos.writeInt(i);
       dos.writeLong(l);
       dos.writeChar(ch);
       dos.writeBoolean(bl);
       dos.writeFloat(f);
       dos.writeDouble(d);
       dos.close();
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:8种基本类型的数据以二进制形式写入指定的文件中。
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    Demo8:从指定的文件中读取8种基本类型的数据
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
      public   class  StreamDemo  {
      
        public   static   void  main(String[] args)  throws  Exception  {
       
       FileOutputStream fos  =   new  FileOutputStream( " dos.txt " );   //  获得写入文件功能 
        BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  //  获得缓冲功能 
        DataOutputStream dos  =   new  DataOutputStream(bos);   //  获得写入基本类型功能 
        
         /* 
        * 定义8种基本类型的对象
         */ 
        byte  b  =   3 ;
        short  s  =   4 ;
        int  i  =   78 ;
        long  l  =   100000 ; 
        char  ch  =   ' a ' ;
        boolean  bl  =   false ;
        float  f  =   4.5f ;
        double  d  =   4.0001 ;
       
         /* 
        * 将8种基本类型的对象写入文件中
         */ 
       dos.writeByte(b);
       dos.writeShort(s);
       dos.writeInt(i);
       dos.writeLong(l);
       dos.writeChar(ch);
       dos.writeBoolean(bl);
       dos.writeFloat(f);
       dos.writeDouble(d);
       dos.close();
       
       FileInputStream fis  =   new  FileInputStream( " dos.txt " );
       BufferedInputStream bis  =   new  BufferedInputStream(fis);
       DataInputStream dis  =   new  DataInputStream(bis);
       System.out.println(dis.readByte());
       System.out.println(dis.readShort());
       System.out.println(dis.readInt());
       System.out.println(dis.readLong());
       System.out.println(dis.readChar());
       System.out.println(dis.readBoolean());
       System.out.println(dis.readFloat());
       System.out.println(dis.readDouble());
       dis.close();
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:数据正常输出:
    3
    4
    78
    100000
    a
    false
    4.5
    4.0001
    -------------------------------------------------------------------------------

    4、PipedInputStream和PipedOutputStream

    管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。
    -------------------------------------------------------------------------------
    ------------
    Java API:
    ------------
    java.io
    类 PipedInputStream
    java.lang.Object
      java.io.InputStream
          java.io.PipedInputStream
    所有已实现的接口:
    Closeable
    public class PipedInputStream
    extends InputStream

    传送输入流应该连接到传送输出流;传送输入流会提供要写入传送输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能会死锁该线程。传送输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。
    从以下版本开始:
    JDK1.0
    -------------------------------------------------------------------------------
    ------------
    Java API:
    ------------
    java.io
    类 PipedOutputStream
    java.lang.Object
      java.io.OutputStream
          java.io.PipedOutputStream
    所有已实现的接口:
    Closeable, Flushable
    public class PipedOutputStream
    extends OutputStream

    传送输出流可以连接到传送输入流,以创建通信管道。传送输出流是管道的发送端。通常,数据由某个线程写入 PipedOutputStream 对象,并由其他线程从连接的 PipedInputStream 读取。不建议对这两个对象尝试使用单个线程,因为这样可能会死锁该线程。

    从以下版本开始:
    JDK1.0
    -------------------------------------------------------------------------------
    ------------
    Java API:
    ------------
    connect
    public void connect(PipedInputStream snk)
                 throws IOException
    将此传送输出流连接到接收者。如果此对象已经连接到其他某个传送输入流,则抛出 IOException。

    如果 snk 为未连接的传送输入流,而 src 为未连接的传送输出流,则可以通过以下任一调用使其连接:
    src.connect(snk)
    或:
    snk.connect(src)
    这两个调用的效果相同。

    参数:
    snk - 要连接的传送输入流。
    抛出:
    IOException - 如果发生 I/O 错误。
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    Demo9:利用管道输入流和输出流进行通讯。
    -------------------------------------------------------------------------------

    import  java.io. * ;
      
      public   class  PipedStreamDemo  {
      
        public   static   void  main(String[] args)  {
       PipedOutputStream pos  =   new  PipedOutputStream();
       PipedInputStream pis  =   new  PipedInputStream();
       
         try   {
        pos.connect(pis); 
         // pis.connect(pos); 二选一即可 
         
         new  Producer(pos).start();
         new  Consumer(pis).start();
        }   catch  (IOException e)  {
         //  TODO 自动生成 catch 块 
         e.printStackTrace();
       } 
      } 
      
     } 
      
      /* 
      * 生产者线程
       */ 
      class  Producer  extends  Thread  {
      
       private  PipedOutputStream pos;
      
        public  Producer(PipedOutputStream pos)  {
        this .pos  =  pos;
      } 
      
        public   void  run()  {
         try   {
        pos.write( " Hello, welcome you! " .getBytes());
        pos.close();
        }   catch  (Exception e)  {
        e.printStackTrace();
       } 
      } 
      
     } 
      
      /* 
      * 消费者线程
       */ 
      class  Consumer  extends  Thread  {
      
       private  PipedInputStream pis;
      
        public  Consumer(PipedInputStream pis)  {
        this .pis  =  pis;
      } 
      
        public   void  run()  {
         try   {
         byte [] buf  =   new   byte [ 100 ];
         int  len  =  pis.read(buf);
        System.out.println( new  String(buf,  0 , len));
        pis.close();   //  关闭输入流 
        }   catch  (Exception e)  {
        e.printStackTrace();
       } 
      } 
      
     }

    -------------------------------------------------------------------------------
    运行结果:输出Hello, welcome you!
    -------------------------------------------------------------------------------

    转自:http://www.blogjava.net/coderdream/articles/65609.html

  • 相关阅读:
    一篇笔记整理JVM工作原理
    深入理解java异常处理机制
    Javaee----重新回顾servlet
    dubbo框架----探索-大型系统架构设计(图解)
    Java 中浮点数---------BigDecimal和double(初探)
    dubbo框架----初探索-配置
    ConcurrentHashMap-----不安全线程hashmap-安全线程-hashtable
    Maven Eclipse (m2e) SCM connector for subclipse 1.10 (svn 1.8) 无法检测
    从svn检出项目---------不是web项目
    Java当中的内存分配以及值传递问题内存解析
  • 原文地址:https://www.cnblogs.com/llkmst/p/4727547.html
Copyright © 2011-2022 走看看