Java IO 技术之基本流类

流式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。

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() :关闭输出流,释放和这个流相关的系统资源。

 

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
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

时间: 2024-10-06 08:42:31

Java IO 技术之基本流类的相关文章

JAVA之IO技术-自定义的LineNumberReader类

package ioTest.io2; /* * 自定义一个带有读取行号方法的读取文件的装饰类 */ import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class MyLineNumberReaderDemo { public static void main(String[] args) throws IOException { String line; //创建输入流-读取

J2SE知识点归纳笔记(七)---Java IO Part 1:File类与RandomAccessFile类

J2SE知识点归纳笔记(七)---Java IO Part 1:File类与RandomAccessFile类                                                                 --转载请注明出处:coder-pig 本节引言: 兜兜转转,又回来写Java了,上一篇J2SE知识点归纳笔记(六)---Java常用类是上2014.4.14写的,时隔一年 又来重拾之前还没写完的系列了,前些天群里一个妹子反映她Java基础薄弱,然后抱怨在cs

JavaLearning:JAVA IO 之内存操作流

package org.fun.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; public class ByteArrayDemo { public static void main(String[] args) { String str = "helloworld";// 定义字符串,全部由小写字母组成 ByteArrayOutputStream bos = null;//

Java IO 字节流与字符流 (二)

概述 IO流用来处理设备之间的数据传输 Java对数据的操作时通过流的方式 Java用于操作流的对象都在IO包中 流按操作的数据分为:字节流和字符流 流按流向不同分为:输入流和输出流 IO流常用基类 字节流的抽象基类 InputStream,OuputStream 字符流的抽象基类 Reader,Writer 注: 这些基类的子类都是以基类的名称结尾的,如FileReader,FileInputStream 字节流 字节流:以字符为导向的流 简单介绍一个例子,演示字节流对图片的复制 1: imp

java IO 四(转换流的使用)

扯点别的: 随着年龄的慢慢增长,有些道理才明白,有些爱才感慨.家人或许希望你能立足大城市,开创一番事业.但是在内心里家人永远希望你多花点时间陪陪他们,一起吃吃饭,说说话,只要你平平安安,生活快乐,家人就感到幸福.所以多花点时间陪陪父母.陪陪爱人.陪陪孩子. 又搁置了不短的时间,继续写java io的知识,现在感觉自己的记忆力真的不行了,总是记不住东西,哎,关键还是理解不够深入,靠死记硬背是不行的看样.开搞.参考自毕向东老师的视频 第一: InputStreamReader 看看JDK里面的解释,

JAVA IO 字节流与字符流

文章出自:听云博客 题主将以三个章节的篇幅来讲解JAVA IO的内容 . 第一节JAVA IO包的框架体系和源码分析,第二节,序列化反序列化和IO的设计模块,第三节异步IO. 本文是第一节.       IO框架 从上图我们可以看出IO可以分为两大块 字节流和字符流 字节流是 InputStream 和 OutputStream 分别对应输入与输出 字符流是Reader和Writer分别对应输入与输出        ByteArrayInputStream  它字节数组输入流.继承于InputS

java io 学习之三 字符流的缓冲区

 /** 字符流的缓冲区 缓冲区的出现,提高了对数据的读写效率 对应的类: BufferedWriter BufferedReader 缓冲区要结合流才可以使用 缓冲区是在流的基础上对流的功能进行增强 软件的优化可以分为:设计优化和性能优化 设计优化:对代码进行重构,让代码实现更强的可扩展性和灵活性,复用性. 提高性能最常用的的手段是:缓冲区  线程池 BufferedWriter 构造方法摘要 BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输

java.io 字节流与字符流及简单实例

java io是java中非常基础的知识点,对于通信和不涉及到数据库的项目java io应该是要经常使用.java io分为字节流和字符流,分清字节流和字符流的异同是掌握java io的起点. 字节流,最小单位是字节,通信协议中的X-MODEM和Y-MODEM协议传输单位就是字节流.java io中与字节流相关的主要类有:InputStream,OutputStream,FileInputStream,FileOutputStream.与字符流有关的主要类有:Writer,Reader,File

java IO(三):字符流

*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hljs-comment, .hljs-template_comment, .diff .hljs-header, .hljs-javadoc { color: #998; font-style: italic; } .hljs-keyword, .css .rule .hljs-keyword, .h