java io (中)

java io的流式部分

参考链接:http://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html

http://blog.csdn.net/wwww1988600/article/details/8835813?utm_source=tuicool&utm_medium=referral


一.io流的介绍:

    流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流(即输入流),这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流(输出流)。


二.io流的四个基本类:

     java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流:


    2.1  io流类图结构:


    2.2 io流分类

    流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
   1)  字节流:数据流中最小的数据单元是字节。
   2)  字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

   

   字符与字节的区别与联系:

   字节:是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制。

   字符:字符是人们使用的记号,抽象意义上的一个符号。

   字符通过不同的编码方式(ascii码制)与二进制码进行对应,而8位二进制码即为一个字节


   用字符流和字节流处理文件类型的不同:

  (1) 文件中显示的是字符,如果将文件作为字节输入流或者输出流的源,那么在读写过程中必然会发生char类型与byte类型的转换,那么java是如何转换的呢?

   char是字符类型,java使用的unicode编码,当字符类型与数值类型(如int,byte)的转化是通过unicode编码的对应关系进行转换的。

   例如:char a='a'; 

           byte b=(byte)a; // 打印b,输出97;

           int  t=a;  //打印t,输出97;

           char c=a+10; //打印c,输出k;

     (2)用字符流处理文件时,用char[]数组进行数据的存储,所以不会发生类型转换,


三.Java IO流对象

   3.1.输入字节流InputStream

    InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream  的流都是向程序中输入数据的,且数据单位为字节(8bit);

InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法: 
 (1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
 (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的 
 (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。 
 (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用, 
 (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取 
 (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭. 

  

   主要的子类(都实现了抽象类的方法):

        

   

    FileInputStream

    把一个文件作为输入流,实现对文件的读取操作  

    构造方法:    
    File  fin=new File("d:/abc.txt"); 
    FileInputStream in=new FileInputStream( fin);

    然后用in调用read方法进行读操作


    ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用 

   

    StringBufferInputStream:把一个String对象作为InputStream 
    

    PipedInputStream:实现了pipe的概念,主要在线程中使用 
   

    SequenceInputStream:把多个InputStream合并为一个InputStream


    Bufferedinputstream:

    BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能;BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式(软工设计模式,留坑)。

    使用方法:

    int SIZE=1024;

    byte b[]=new byte[100];

    File f=new File("...");

    FileInputStream input=new FileInputStream(f);

    BufferedInputStream bis=new BufferedInputStream(input,2*SIZE);//指定文件带缓冲区的读取流且指定缓冲区大小为2KB

    bis.read(b);//将数据读入b数组


   3.2  输出字节流OutputStream

    OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。 
 1. public void write(byte b[ ]):将参数b中的字节写到输出流。 
 2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。 
 3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。 
 4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。 
 5. public void close( ) : 关闭输出流并释放与流相关的系统资源。 

    

   主要的子类(均实现了以上的方法)

        


       1) FileOutputStream:把信息存入文件中 ,构造器第二个boolean类型的参数:true表示写在文件末尾

      

      2) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中 
      

      3) PipedOutputStream:实现了pipe的概念,主要在线程中使用 
     

      4) SequenceOutputStream:把多个OutStream合并为一个OutStream 


      5)BufferedOutputStream: 与BufferedIutputStream是一对流,BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。


      6)PrintStream:打印流,构造器里可以是File类型,String(代表文件路径),outputstream类型, 
printstream有print()方法,print()里参数会打印到printstream的构造器里的对象里。

    

     3.3 字符输入流Reader

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

   主要子类:

       

      

     FileReader :字符流处理文件 

      主要用来读取字符文件,使用缺省的字符编码(unicode) 
      

      CharArrayReader:字符流处理字符数组,
   

      StringReader : 字符流处理字符串 
   

      InputStreamReader :从输入流读取字节,再将它们转换成字符:Public inputstreamReader(inputstream is); 
  

      FilterReader: 用于过滤字符流 
         
   BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。 
     

     

     主要方法:

      (1)  public int read() throws IOException; //读取一个字符,返回值为读取的字符 

   (2)  public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/ 
   (3)  public abstract int read(char cbuf[],int off,int len) throws IOException; 
  /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/ 


    3.4 字符输出流Writer

     写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:

    

        1)FileWrite:  将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。 
  Public FileWrite(file f); 
  

        2)  chararrayWrite:  将字符缓冲器用作输出。 
   Public CharArrayWrite(); 
  

        3)  PrintWrite: 生成格式化输出,同上printstream。不同的是构造器的传入的是字符流而不是字节流。
      public PrintWriter(outputstream os); 
  

        4) filterWriter: 用于写入过滤字符流 
      protected FilterWriter(Writer w); 
  

        5) PipedWriter:处理线程的字符流   

        

        6) StringWriter:无与之对应的以字节为导向的stream  

      

        7) OutputStreamReader:  将输出字节流传入构造器,再将它们转换成字符流:Public outputstreamReader(outputstream is);

    

        主要方法:

  (1)  public void write(int c) throws IOException; //将整型值c的低16位写入输出流 
  (2)  public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流 
  (3)  public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流 
  (4)  public void write(String str) throws IOException; //将字符串str中的字符写入输出流 
  (5)  public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流 
  (6)  flush( ) //刷空输出流,并输出所有被缓存的字节。 
  (7)  close()    关闭流 public abstract void close() throws IOException



       3.5 使用read(),或者readline()打印读取的数据
       
     思考:字节流的read方法,和字符流的read方法(读取一个字节或者一个字符)的返回值为什么是都是int
    
      对于字节流的read():

       * 如果返回byte, 无法表示流末尾.
   * byte的取值范围是从-128到127
   * 这个范围内所有的数据, 都有可能在数据中出现
   * read()方法需要返回一个特殊的值来表示流末尾, 这个值不能和流中的数据重复
     
     对于字符流的read():
      如果返回char, 那么无法表示流末尾. 
   * char的取值范围是从0到65535
   * 这个范围内的所有字符, 都有可能在数据中出现
   * 我们需要使用一个不可能在数据中出现的值来表示流末尾
   * 那么Java中就是用-1来表示这个末尾的, 因为-1不会在数据中出现,而为了返回-1, 那么只能用int
    

    综上:为了能够有一个表示读到文件末尾的特殊符号,所以需要char类型或者byte类型到int类型的转换。
转换规则如下:    
      char转为int:   字符流中读取到的char是直接当作int使用, 例如读取到一个'a'也就是97的时候, 那么就相当于返回了一个int的97
        byte转化为int字节高位补0转为int返回, 这样做所有的数据都会是正数, 而改变后的数据只要强转回byte, 就可以得到原有数据
          
    
     用read()来打印文件中的内容:

                File file=new File("C:/Users/WWWYU/Desktop/test.txt");
	        FileInputStream fis=new FileInputStream(file);
		int t=0;
		while((t=fis.read())!=-1){
			System.out.print((char)t);
		}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值