IO流总结

IO流总结

字符流的由来:


早期处理数据都是字节数据,使用字节流技术就可以完成了。

因为后期编码表的不断出现,识别某一文字的码表不唯一。比如中文,GBK,unicode都可以识别。
就出出现了编码问题。

中文字节数据 gbk --> 流处理--->gbk解析可以了。

后期:容器出现这样的问题:
中文字节数据gbk --> 流处理 unicode来处理-->数据错误。

为了处理文字数据,就需要通过 字节流技术+编码表 相结合来完成。注意:只有文字是这样的,因为文字涉及编码问题。
其他数据比如dvd mp3 图片等是不涉及这个问题的。

虽然字节流+编码表可以解决文字数据处理问题,但是较为麻烦。
为了便于使用,将字节流和编码表进行了封装,就出现了便于文字操作的流技术:字符流。
其实字符流就是:字节流+编码表。
-----------------------------

IO的体系:

    按流的方向划分:
        输入流:读数据
        输出流:写数据
    按照流的操作单位:
        字节流:
        字符流
    
    InputSteam:字节输入流
    OutputStream:字节输出流
    
    Reader:字符输入流
    Writer:字符输出流
    
    标准流
    System.in:标准输入流  读键盘
    System.out:标准输出流  控制台
    
学习io流体系:看顶层(父类共性功能),用底层(子类具体对象)。

该体系的一个好处就是:
每个子类的后缀名都是所属体系的父类的名称,很容易区分所属的体系。
而且每一个子类前缀名都是该子类对象的功能体现。
这样我们在使用io体系中的对象时,就非常容易查找了。


//需求:读取一个硬盘上的文本文件,将数据打印到控制台上。
思路:
1,读取无非就是将硬盘的数据弄到内存中。要使用到输入流。
2,既然是文字,可以使用字符流,一综合使用字符输入流,该体系时Reader.
3,既然要读取一个文本文件。可以使用 FileReader:用于读取字符文件的便捷类。



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

字符流的缓冲区。

BufferedReader
BufferedWriter

缓冲区给给流的操作动作(读写)提高效率.所以缓冲区的对象建立必须要有流对象。


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

字符流:
FileReader
FileWriter

BufferedReader
BuffereWriter

字节流。
InputStream  OutputStream

FileInputStream FileOutputStream
BufferedInputStream BufferedOutputStream



转换流:
字节流--->字符流的桥梁。InputStreamReader
字符流--->字节流的桥梁。OutputStreamWriter

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

流的操作规律:

在进行数据操作时,IO包中提供了N多对象不同功能来操作设备上的数据。
在实际开发时,到底用哪个流对象来完成数据处理呢?
这是我们最为苦恼的事情。
如何明确具体用哪个流对象呢?


规律就是四个明确?

1,明确源和目的。
    源:InputStream   Reader 一定是被读取的。
    目的:OutputStream  Writer 一定是被写入的。
    
2,处理的数据是否是纯文本的数据?
    是:使用字符流。Reader Writer
    否:使用字节流。    InputStream OutputStream
    
    如果是源并且是纯文本,Reader
    如果是目的并且是纯文本,Writer
    
    到这里,两个明确确定完,就可以确定出要使用哪个体系。
    
    接下来,就应该明确具体这个体系要使用哪个具体的对象。
3,明确数据所在的设备:
    源设备:
        键盘(System.in)
        硬盘(FileXXX)FileReader FileInputStream
        内存(数组)ByteArrayInputStream CharArrayReader StringReader
        网络(Socket)
    目的设备:
        显示器(控制台System.out)
        硬盘(FileXXX)FileWriter FileOutputStream
        内存(数组)ByteArrayOutputStream CharArrayWriter StringWriter
        网络(Socket)
    
    具体使用哪个对象就可以明确了。
    
4,明确是否需要额外功能?
    1,是否需要高效?缓冲区Buffered 四个。
    2,是否需要转换?转换流    InputStreamReader OutputStreamWriter    
    3,是否操作基本数据类型? DataInputStream  DataOutputStream
    4,是否操作对象(对象序列化)? ObjectInputStream ObjectOutputStream
    5,需要对多个源合并吗? SequenceInputStream
    6,需要保证数据的表现形式到目的地吗? PrintWriter
    
如果数据有规律,并且源和目的都是file,需要随机访问时,可以使用RandomAccessFile工具类。
    

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

eg
需求1:复制一个文本文件。
    1,明确源和目的:既有源,又有目的。
        源:InputStream Reader
        目的:OutputStream Writer.
    2,明确是否是纯文本?是!
        源:Reader
        目的:Writer
        
    3,明确具体设备:
        源:
            硬盘(file)
        目的:
            硬盘(file)
        
        源对应的体系Reader中可以操作硬盘设备的对象是 FileReader
        目的对应的体系Writer中可以操作硬盘设备的对象是FileWriter
        
    直接明确具体对象并创建。
    FileReader fr = new FileReader("a.txt");
    FileWriter fw = new FileWriter("b.txt");
    
    //就是频繁的读写操作。自己补上。
    
    4,需要额外功能吗?
        需要,高效。 使用缓冲区。
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
        
        


eg2:复制一个图片
    1,明确源和目的:既有源,又有目的。
        源:InputStream Reader
        目的:OutputStream Writer.
    2,明确是否是纯文本?不是!
        源:InputStream
        目的:OutputStream
    3,明确设备:
        源:硬盘
        目的:硬盘:
        FileInputStream fis = new FileInputStream("1.jpg");
        FileOutputStream fos = new FileOutputStrema("2.jpg");


eg3:读取键盘录入,存储到一个文件中。

    1,明确源和目的:既有源,又有目的。
        源:InputStream Reader
        目的:OutputStream Writer.
    2,明确是否是纯文本?一般键盘录入的都是文字,所以是纯文本的。
        源:Reader
        目的:Writer
    3,明确设备:
        源:键盘。
        目的:硬盘。
        
        具体对象
            源是:System.in.
            目的是:FileWriter
            
        InputStream in = System.in;
        FileWriter fw = new FileWriter("a.txt");
        对这个读写,应该这样完成,通过键盘录入读取字节数据,先不做写入操作,
        而是将字节数据临时存储,转成字符串,然后在交给fw写入。
        
        发现代码操作的起来很麻烦。有没有已有的功能可以解决这个问题啊?
    4,需要额外功能吗?
        需要。必须的。
        需要将键盘录入的字节转成字符。
        使用转换流。而且是 将字节-->字符的转换流对象。InputStreamReader
        
        InputStreamReader isr = new InputStreamReader(System.in);
        FileWriter fw = new FileWriter("a.txt");
            
        还需要其他功能吗?
        需要,高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));
        
        
    

eg4:读取一个文本文件,显示到显示器上。
    1,明确源和目的:既有源,又有目的。
        源:InputStream Reader
        目的:OutputStream Writer.
    2,明确是否是纯文本?是。
        源:Reader
        目的:Writer
    3,明确设备:
        源:硬盘。File
        目的:显示器。System.out
    
        FileReader fr = new FileReader("a.txt");
        OutputStream out = System.out;
        这已经可以完成读写了。
        通过fr读取文本到字符数组,将字符数组转成字符串,然后在将字符串转成字节数组。
        交给out输出。
        就是这个转换动作都需要自己完成。烦!
        有没有已有的功能可以解决这个问题啊?
    4,需要额外功能吗?必须的。
        转换。需要将已有的字符数据转成字节。字符-->字节的桥梁 OutputStreamWriter
        FileReader fr = new FileReader("a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        
        需要高效。
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWrier(System.out));
        
        
------------------------------

eg5:读取一个文本文件,将文件中文本按照指定的编码表UTF-8写入到另一个文件中。
    1,明确源和目的:既有源,又有目的。
        源:InputStream Reader
        目的:OutputStream Writer.
    2,明确是否是纯文本?是。
        源:Reader
        目的:Writer
    3,明确设备:
        源:硬盘。File
        目的:硬盘。File
    
        FileReader fr = new FileReader("a.txt");
        FileWriter fw = new FileWriter("b.txt");
        
        这样做不行,满足不了需求,为什么呢?
        因为这个两个对象在操作文本数据,都是用了默认的编码表。在我的本机中默认码表是GBK.
        而需求中希望写入到文件的数据是按照utf-8的码表。
        
        其实这两个对象就是字节流+默认编码表。
        
        
        源对象不变。
        FileReader fr = new FileReader("a.txt");
        需要目的为指定编码表。
        这时就要用到转换流。因为转换流中可以指定具体的编码表。 需要往里传递一个字节流,而且要操作文件,FileOutputStream
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8");
        

        需要高效
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8"));

















以下部分的内容,要求必须理解!

c:\\1.txt 源是一个文件也是字节数据,是不是应该使用字节流呢?


FileInputStream fis = new FileInputStream("c:\\1.txt");
InputStreamReader isr = new InputStreamReader(fis,"gbk");

isr.read();//字符。

既然是明确操作是文件,而且使用默认编码表。
可以使用InputStreamReader的子类。FileReader

FileReader fr = new FileReader("c:\\1.txt");


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

File类:
    专门用于描述系统中文件或者文件夹的对象。
    可以用于操作文件或者文件夹的属性信息。
    
    学习具体方法使用,还是按照面向对象的原则:
    如果将一个文件或者文件夹封装成对象,那么这个对象具备什么功能,
    方便于对文件或者文件夹的操作呢?
    
    1,获取文件信息。
        获取名称,
        获取路径。
        获取大小。
        获取时间。
        ...
    2,判断。
        是只读的不?
        是隐藏的不?
        
    3,文件的创建和删除以及该文件是否存在,文件对象自己最清楚。
        具体创建,删除,是否存在等功能。
        
    
------------------------------------------------

IO流体系:

字符流:
Reader
    |--BufferedReader:
        |--LineNumberReader
    |--CharArrayReader
    |--StringReader
    |--InputStreamReaer
        |--FileReader


Writer
    |--BufferedWriter
    |--CharArrayWriter
    |--StringWriter
    |--OutputStreamWriter
        |--FileWriter
    |--PrintWriter



字节流:
InputStream
    |--FileInputStream:
    |--FilterInputStream
        |--BufferedInputStream
        |--DataInputStream
    |--ByteArrayInputStream
    |--ObjectInputStream
    |--SequenceInputStream
    |--PipedInputStream


OutputStream
    |--FileOutputStream
    |--FilterOutputStream
        |--BufferedOutputStream
        |--DataOutputStream
    |--ByteArrayOutputStream
    |--ObjectOutputStream
    |--PipedOutputStream
    |--PrintStream


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值