码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员------Java中IO流学习总结

时间:2015-02-23 10:50:57      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

Java培训、Android培训、iOS培训、.Net培训。期待您的交流

一、概念

流:流就是字节序列的抽象概念,能被连续读取数据的数据源和能被连续写入数据的接收端就是流

IO流:用于处理设备上的数据

    常用设备:硬盘、内存、键盘录入等

IO流的分类:

  1、根据处理的数据类型不同,可分为字节流和字符流。

    字符流的由来:因为文件编码的不同,而有了对字符高效操作的字符流对象,原理是基于字节流读取字节时,去查了相关码表。

    字符流和字节流的区别:

      **字节流读取时,读到一个字节就返回一个字节;而字符流是字节流一次读取一个或多个字节,然后去查相应的码表,将查到的字符返回。

      **字节流可以处理所有数据类型;而字符流只能够处理字符数据。   

  2、根据流的流向不同,可分为输入流和输出流。

二:IO体系继承关系图

技术分享

三:功能

IO体系具备的最基本的两个功能:读取和写入。

  1、字节流:InputStream(读取)和OutputStream(写入)。

  2、字符流:Reader(读)和Writer(写)。

字符流基本的读写操作:

先看Reader和Writer

继承关系:

Reader

  InputStreamReader

      FileReader:专门用于处理文件的字符读取流对象

Writer

  OutputStreamReader

      FileWriter:专门用于处理文件的字符写入流对象

Reader中的常用方法:

  1、int read():读取一个字符,返回读取到的字符。如果已经读到流的末尾,则返回-1;

  2、int raad(char[]):将读取到的字符存入指定的字符数组中,返回的是读到字符的个数,如果已经读到流的末尾,则返回-1;

  3、close();:关闭流,释放资源。

Writer中的常用方法:

  1、write(ch):将一个字符写入到流中。

  2、write(char[]):将一个字符数组写入到流中。

  3、write(String):将一个字符串写入到流中。

  4、flush():将流中的数据刷新到数据目的地,流依然存在。

  5、close():关闭流。在关闭资源之前先将流中的数据flush()到数据目的中。

FileReader:

  1、用于读取文本文件的流对象。

  2、用于关联文本文件。

  构造函数:FileReader(String fileName);

      在读取流对象被初始化的时候,必须指定一个被读取的文件。

      如果文件不存在,则会发生FileNotFoundException

FileWriter:

  1、用于处理文本文件

  2、该类中有默认的编码表

  3、该类中有临时缓冲区

  构造函数:FileWriter(String fileName)

          在写入流对象初始化时,必须指定一个存储数据的目的地。

          如果文件不存在,则系统会创建一个文件。

          如果文件存在,则会被覆盖。

       FileWriter(String fileName,boolean append):

          当append为true时,则会在文件的末尾处进行数据的续写。

代码示例:

技术分享
//将C盘一个文本文件复制到D盘。
/*
复制的原理:
其实就是将C盘下的文件数据存储到D盘的一个文件中。

步骤:
1,在D盘创建一个文件。用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。
*/

import java.io.*;

class CopyText 
{
    public static void main(String[] args) throws IOException
    {
        copy_2();
    }

    public static void copy_2()
    {
        FileWriter fw = null;
        FileReader fr = null;
        try
        {
            fw = new FileWriter("SystemDemo_copy.txt");
            fr = new FileReader("SystemDemo.java");

            char[] buf = new char[1024];

            int len = 0;
            while((len=fr.read(buf))!=-1)
            {
                fw.write(buf,0,len);
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("读写失败");
        }
        finally
        {
            if(fr!=null)
                try
                {
                    fr.close();
                }
                catch (IOException e)
                {
                }
            if(fw!=null)
                try
                {
                    fw.close();
                }
                catch (IOException e)
                {
                }
        }
    }

    //从C盘读一个字符,就往D盘写一个字符。
    public static void copy_1()throws IOException
    {
        //创建目的地。
        FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");

        //与已有文件关联。
        FileReader fr = new FileReader("RuntimeDemo.java");

        int ch = 0;

        while((ch=fr.read())!=-1)
        {
            fw.write(ch);
        }  
        fw.close();
        fr.close();
    }
}
技术分享

字符流的缓冲区:

缓冲区的出现提高了对流的操作效率,其实现的原理就是在内部对数组进行了封装。

对应的对象:

    BufferedReader

      特有方法:readLine():一次读一行,读到行标记时,就将行标记前的字符串返回,读到末尾时返回null。

    BufferedWriter

      特有方法:newLine():跨平台的换行符,用于写入一个换行符到流中。

使用缓冲区技术的文本复制代码:

技术分享
/*
通过缓冲区复制一个.java文件。
*/
import java.io.*;
class  CopyTextByBuf
{
    public static void main(String[] args) 
    {
        BufferedReader bufr = null;
        BufferedWriter bufw = null;

        try
        {
            bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
            bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));

            String line = null;

            while((line=bufr.readLine())!=null)
            {
                bufw.write(line);
                bufw.newLine();
                bufw.flush();

            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("读写失败");
        }
        finally
        {
            try
            {
                if(bufr!=null)
                    bufr.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("读取关闭失败");
            }
            try
            {
                if(bufw!=null)
                    bufw.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("写入关闭失败");
            }
        }
    }
}
技术分享

字节流的读写操作:

抽象积累:InputStream和OutputStream

字节流可以操作任何数据。

同样以缓冲区拷贝一段MP3文件的代码为例:

技术分享
/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
为简化代码,将异常抛出。
*/
import java.io.*;
class  CopyMp3
{
    public static void main(String[] args) throws IOException
    {
        long start = System.currentTimeMillis();
        copy_2();
        long end = System.currentTimeMillis();

        System.out.println((end-start)+"毫秒");
    }

    public static void copy_2()throws IOException
    {
        MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));
        
        int by = 0;

        //System.out.println("第一个字节:"+bufis.myRead());

        while((by=bufis.myRead())!=-1)
        {
            bufos.write(by);
        }

        bufos.close();
        bufis.myClose();
    }

    //通过字节流的缓冲区完成复制。
    public static void copy_1()throws IOException
    {
        BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
        
        int by = 0;

        while((by=bufis.read())!=-1)
        {
            bufos.write(by);
        }
        bufos.close();
        bufis.close();        
    }
}
技术分享

 

转换流:

特点: 
    1、是字节流和字符流之间的桥梁。 
    2、该流对象中可以对读取到的字节数据进行指定编码表的编码转换。

什么时候使用呢? 
    1、当字节和字符之间有转换动作时。 
    2、流操作的数据需要进行编码表的指定时。

具体的对象体现: 
    1、InputStreamReader:字节到字符的桥梁。 
    2、OutputStreamWriter:字符到字节的桥梁。 

构造函数: 
    InputStreamReader(InputStream):通过该构造函数初始化,使用的是本系统默认的编码表 GBK。 
    InputStreamReader(InputStream,String charSet):通过该构造函数初始化,可以指定编码表。 
    OutputStreamWriter(OutputStream):通过该构造函数初始化,使用的是本系统默认的编 码表GBK。 
    OutputStreamWriter(OutputStream,String charSet):通过该构造函数初始化,可以指定编码 表。 操作文件的字符流对象是转换流的子类。 

  转换流中的read方法。已经融入了编码表, 在底层调用字节流的read方法时将获取的一个或者多个字节数据进行临时存储, 并去查指定的编码表,如果编码表没有指定, 查的是默认码表。那么转流的read方法就可以返回一个字符比如中文。 转换流已经完成了编码转换的动作,对于直接操作的文本文件的FileReaer而言,就不 用在重新定义了, 只要继承该转换流,获取其方法,就可以直接操作文本文件中的字符数据了。

 

总结:流操作的基本规律:

     1、明确数据源和数据目的。其实是为了明确输入流还是输出流。

     2、明确操作的数据是否是纯文本数据。其实是为了明确字符流还是字节流。

        数据源:键盘System.in, 硬盘(File开头的流对象),内存(数组)。

        数据目的:控制台System.out, 硬盘(File开头的流对象),内存(数组)。

黑马程序员------Java中IO流学习总结

标签:

原文地址:http://www.cnblogs.com/alvis2015/p/4297890.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!