Java IO 技术之基本流类

    技术2022-05-19  24

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

    很好的一篇文章,谢谢作者

     

    流式IO 流(Stream)是字节的源或目的。 两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。 流的分类 节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。 过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。 InputStream 三个基本的读方法       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。 java.io包中 InputStream的类层次 OutputStream 三个基本的写方法      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() :关闭输出流,释放和这个流相关的系统资源。 java.io包中 OutputStream的类层次

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

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6    int  data;  7     8    while  ((data  =  System.in.read())  !=   - 1 {  9    System.out.write(data); 10   } 11 12  } 13 14 } 15

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

    基本的流类 1、FileInputStream和FileOutputStream       节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。 ------------------------------------------------------------------------------- Demo2:将字符串写入特定文件,注意write方法只接收字符数组。 -------------------------------------------------------------------------------

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6   FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );  7  8    /*  9    * 注意:FileOutputStream的write方法接收字符数组,不能接收String字符串, 10    * 所以要用String的getBytes方法生成一个字符数组 11     */ 12   fos.write( " http://www.cnblogs.com " .getBytes());  13   fos.close(); 14 15  } 16 17 }

    ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- 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特定的构造方法。 -------------------------------------------------------------------------------

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6   FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );  7  8    /*  9    * 注意:FileOutputStream的write方法接收字符数组,不能接收String字符串, 10    * 所以要用String的getBytes方法生成一个字符数组 11     */ 12   fos.write( " http://www.cnblogs.com " .getBytes());  13   fos.close(); 14    15    //  使用String的这个构造方法: 16    //  String(byte[] bytes, int offset, int length) 17    18   FileInputStream fis  =   new  FileInputStream( " 1.txt " ); 19    byte [] buf  =   new   byte [ 100 ]; 20    int  len  =  fis.read(buf); 21    22    //  使用String的这个构造方法: 23    //  String(byte[] bytes, int offset, int length) 24   System.out.println( new  String(buf,  0 , len)); 25   fis.close();   //  使用完后记得关闭文件流 26 27  } 28 29 } 30 31

    ------------------------------------------------------------------------------- 运行结果:http://www.cnblogs.com -------------------------------------------------------------------------------

    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类的子类,所以可以用它来构造。 -------------------------------------------------------------------------------

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6     7   FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );  8   BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  9   bos.write( " http://www.cnblogs.com " .getBytes()); 10  } 11 12 }

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

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6     7   FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );  8   BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  9   bos.write( " http://www.cnblogs.com " .getBytes()); 10    11   bos.flush(); 12  } 13 14 }

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

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6     7   FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );  8   BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  9   bos.write( " http://www.cnblogs.com " .getBytes()); 10    11   bos.close(); 12  } 13 14 }

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

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

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

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

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6     7   FileOutputStream fos  =   new  FileOutputStream( " 1.txt " );  8   BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  9   bos.write( " http://www.cnblogs.com " .getBytes()); 10    11   bos.close(); 12    13   FileInputStream fis  =   new  FileInputStream( " 1.txt " ); 14   BufferedInputStream bis  =   new  BufferedInputStream(fis); 15    byte [] buf  =   new   byte [ 100 ]; 16    int  len  =  bis.read(buf); 17    18    //  使用String的这个构造方法: 19    //  String(byte[] bytes, int offset, int length) 20   System.out.println( new  String(buf,  0 , len)); 21   bis.close(); 22  } 23 24 }

    ------------------------------------------------------------------------------- 运行结果:输出http://www.cnblogs.com -------------------------------------------------------------------------------

    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对象来构造。 -------------------------------------------------------------------------------

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6     7   FileOutputStream fos  =   new  FileOutputStream( " dos.txt " );   //  获得写入文件功能  8   BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  //  获得缓冲功能  9   DataOutputStream dos  =   new  DataOutputStream(bos);   //  获得写入基本类型功能 10    11    /* 12    * 定义8种基本类型的对象 13     */ 14    byte  b  =   3 ; 15    short  s  =   4 ; 16    int  i  =   78 ; 17    long  l  =   100000 18    char  ch  =   ' a ' ; 19    boolean  bl  =   false ; 20    float  f  =   4.5f ; 21    double  d  =   4.0001 ; 22    23    /* 24    * 将8种基本类型的对象写入文件中 25     */ 26   dos.writeByte(b); 27   dos.writeShort(s); 28   dos.writeInt(i); 29   dos.writeLong(l); 30   dos.writeChar(ch); 31   dos.writeBoolean(bl); 32   dos.writeFloat(f); 33   dos.writeDouble(d); 34   dos.close(); 35  } 36 37 }

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

     1 import  java.io. * ;  2  3 public   class  StreamDemo  {  4  5   public   static   void  main(String[] args)  throws  Exception  {  6     7   FileOutputStream fos  =   new  FileOutputStream( " dos.txt " );   //  获得写入文件功能  8   BufferedOutputStream bos  =   new  BufferedOutputStream(fos);  //  获得缓冲功能  9   DataOutputStream dos  =   new  DataOutputStream(bos);   //  获得写入基本类型功能 10    11    /* 12    * 定义8种基本类型的对象 13     */ 14    byte  b  =   3 ; 15    short  s  =   4 ; 16    int  i  =   78 ; 17    long  l  =   100000 18    char  ch  =   ' a ' ; 19    boolean  bl  =   false ; 20    float  f  =   4.5f ; 21    double  d  =   4.0001 ; 22    23    /* 24    * 将8种基本类型的对象写入文件中 25     */ 26   dos.writeByte(b); 27   dos.writeShort(s); 28   dos.writeInt(i); 29   dos.writeLong(l); 30   dos.writeChar(ch); 31   dos.writeBoolean(bl); 32   dos.writeFloat(f); 33   dos.writeDouble(d); 34   dos.close(); 35    36   FileInputStream fis  =   new  FileInputStream( " dos.txt " ); 37   BufferedInputStream bis  =   new  BufferedInputStream(fis); 38   DataInputStream dis  =   new  DataInputStream(bis); 39   System.out.println(dis.readByte()); 40   System.out.println(dis.readShort()); 41   System.out.println(dis.readInt()); 42   System.out.println(dis.readLong()); 43   System.out.println(dis.readChar()); 44   System.out.println(dis.readBoolean()); 45   System.out.println(dis.readFloat()); 46   System.out.println(dis.readDouble()); 47   dis.close(); 48  } 49 50 }

    ------------------------------------------------------------------------------- 运行结果:数据正常输出: 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:利用管道输入流和输出流进行通讯。 -------------------------------------------------------------------------------

     1 import  java.io. * ;  2  3 public   class  PipedStreamDemo  {  4  5   public   static   void  main(String[] args)  {  6   PipedOutputStream pos  =   new  PipedOutputStream();  7   PipedInputStream pis  =   new  PipedInputStream();  8     9    try   { 10    pos.connect(pis);  11     // pis.connect(pos); 二选一即可 12     13     new  Producer(pos).start(); 14     new  Consumer(pis).start(); 15   }   catch  (IOException e)  { 16     //  TODO 自动生成 catch 块 17    e.printStackTrace(); 18   } 19  } 20 21 } 22 23 /* 24  * 生产者线程 25   */ 26 class  Producer  extends  Thread  { 27   28   private  PipedOutputStream pos; 29   30   public  Producer(PipedOutputStream pos)  { 31    this .pos  =  pos; 32  } 33   34   public   void  run()  { 35    try   { 36    pos.write( " Hello, welcome you! " .getBytes()); 37    pos.close(); 38   }   catch  (Exception e)  { 39    e.printStackTrace(); 40   } 41  } 42   43 } 44 45 /* 46  * 消费者线程 47   */ 48 class  Consumer  extends  Thread  { 49   50   private  PipedInputStream pis; 51   52   public  Consumer(PipedInputStream pis)  { 53    this .pis  =  pis; 54  } 55   56   public   void  run()  { 57    try   { 58     byte [] buf  =   new   byte [ 100 ]; 59     int  len  =  pis.read(buf); 60    System.out.println( new  String(buf,  0 , len)); 61    pis.close();   //  关闭输入流 62   }   catch  (Exception e)  { 63    e.printStackTrace(); 64   } 65  } 66   67 } 68

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


    最新回复(0)