黑马程序员_基础回顾之IO流

---------------------- android培训java培训、期待与您交流! ----------------------

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

IO流:用于操作设备上数据的技术。
IO流,(Input Output)流:
用来处理设备之间的数据传输。
java操作流的对象存储在IO包中。
按流向分为:输入流,输出流。
流按操作数据的方式:字节流,字符流。
字节流就是二进制,
字符流就是字节流加码表。。
日后,只要操作的数据是文本,建议使用字符流更为方便。
字节流:
InputStream  OutputStream
字符流:
Reader Writer

名称规律:
四个体系中的子类们,后缀名都是其所属体系顶层父类的名称,
前缀名都是该子类对象的功能体现。


需求:将一个字符串写入到硬盘的文件中。 

接下来,先查阅一下Writer体系中共性方法。有写字符数组,字符,字符串的方法。
创建子类的对象。 FileWriter ,创建对象时,必须要查阅子类的构造方法摘要。
发现必须要明确数据的目的地。

//1,创建FileWriter对象。并明确具体的目的。用于存储数据。
/*
* 对象一创建,目的文件就被创建了。
* 如果文件已存在,则会被覆盖。
*/
FileWriter fw = new FileWriter("c:\\demo.txt");
//2,将数据写入。调用write方法.将数据写到了缓冲中。
fw.write("abcde");
//3,使用flush方法对缓冲进行刷新。将缓冲中的数据刷到目的地中。 
//fw.flush();
//4,因为java程序在使用系统中的资源,用完后,应该释放。所以可以用关闭来完成,方法是close();
fw.close();
* flush和close的区别:
* flush将缓冲的数据刷到目的地,流可以继续使用。
* close将缓冲的数据刷到目的地,流会被关闭,不能在使用。同时更多的是用于关闭资源。 
装饰设计模式。
解决问题:对对象的功能进行增强。给对象添加一些额外的功能。
装饰和继承的区别。
Writer
|--TextWriter
|--MediaWriter

无论是操作文本的,还是操作媒体的,我们想要提高操作的效率。效率提高最简单的方式是缓冲区。 
利用继承,给每一个对象都定义了具备缓冲功能的子类。
Writer
|--TextWriter
|--BufferTextWriter
|--MediaWriter
|--BufferMediaWriter
虽然该体系可以用,但是 不利于扩展,没增加一个具体的Writer都需要该Writer具备一个带有buffer的子类。
这样这个体系会变的很臃肿。
无非就是加入一个缓冲区提高效率,那么换一种思考方式,不要让每一个对象都具备缓冲区功能,
而是将缓冲技术进行单独的封装,哪个对象需要被缓冲,就和缓冲区关联即可。

BufferWriter是对写方法进行了增强,使用了缓冲技术。
但是最终体现出来的还是写动作。说明带有缓冲的Writer最终也是Writer的一种。也就是说一个子类。
所以体系会变成。

Writer
|--TextWriter
|--MediaWriter
|--BufferWriter
装饰设计模式比继承更为灵活。
记住:装饰类和被装饰类通常都所属于同一个体系。


流的操作规律:
目的:为了明确使用io流对象时,在具体需求下,该用哪个对象来解决问题。

其实通过几个明确来完成具体对象确定的。

明确一:明确数据源,还是数据目的(数据汇)。
数据源:意味着读,InputStream , Reader
数据目的:意味着写,OutputStream , Writer

明确二:明确要操作的数据是否是纯文本数据。 
是纯文本:为了方便于文本操作建议使用字符流。
是纯文本,对于数据源:Reader
是纯文本,对于数据目的:Writer
不是纯文本呢?那还用废话吗?都是字节流嘛!

到了前两个明确,已经可以确定四个体系中一个。
接下来就是要搞清楚到底要用这个体系中的哪个对象。

明确三:明确数据所在的具体设备。
数据源:
硬盘:File打头。
内存:数组。
键盘:System.in
网络:Socket
数据目的:
硬盘:File前缀
内存:数组。
控制台:System.out.
网络:Socket

明确四:明确流操作时,是否需要额外功能?
高效? Buffered
转换?转换流。
...很多。 都是基本基础流之上来的功能流对象。 

需求:读取一个文本文件中的中文,将这些数据按照UTF-8的编码写入到文件中。

FileReader fr = new FileReader("a.txt");

这三句代码的效果一模一样。
FileWriter fw = new FileWriter("b.txt");//GBK. 这个子类对象的出现是为了便于操作字符文件,将本地默认码表+操作文件的字节流进行了封装。、
//但是这个子类也有局限性,1,必须是文件,2,固定码表 本地默认。 
如果想要改变设备,或者码表必须用它的父类。以下两句。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"));//GBK
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"),"GBK");//GBK

明确一:
既有源,又有目的。
源:InputStream  Reader
目的:OuputStream  Writer

明确二:
是否是纯文本?
是!
源:Reader
目的:Writer

明确三:
具体的设备:
源:硬盘,File
目的:硬盘,File

FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");

明确四:
需要额外功能吗?
必须,因为要明确指定的编码,所以目的就不可以使用FileWriter。因为它是固定的编码。
需要转换,字符-->字节。OutputStreamWriter
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");

File:用于描述文件以及文件夹。
主要是用于操作文件以及文件夹的属性信息。
而流只能操作数据。 
好处:可以将任意的文件或者文件夹封装成对象。对象中可以提供用于操作文件或者文件夹的属性和行为。
File类中的构造函数,字段,方法。

File类的常见功能。 
1,创建&删除。
   1.1  创建文件
   boolean createNewFile()throws IOException;
   该方法如果文件已经存在,不会覆盖,返回false。
   1.2 创建文件夹。
   boolean mkdir():创建单级目录。 
   boolean mkdirs():创建多级目录。
   1.3 删除。
   boolean delete();如果删除目录,必须要保证该目录是没有内容的。否则无法删除。、
   因为windows中,删除目录从里往外删除的。
   void deleteOnExit();
  
  
   file
   file.deleteOnExit();
   operate file
   file.delete();
IO包中的其他对象。
1,打印流。 

PrintStream:字节打印流。
特点:
1,提供了更多丰富的功能,比如打印方法。
2,方便打印数据值的表示形式。
3,不抛IO异常。

它是一个用于操作目的的流对象。
它在构造时,可以接受三种类型的数据:
1,File对象。
2,字符串路径。
3,字节输出流。
对于直接操作文件可以指定字符集(编码表)。
PrintWriter:字符打印流。
它在构造时,可以接受四种类型的数据:
1,File对象。
2,字符串路径。
3,字节输出流。
4,字符输出流。
对于直接操作文件可以指定字符集(编码表)。
凡是接收输出流参数的都可以指定boolean参数完成自动刷新。

将指定目录中的指定扩展名的文件的绝对路径写入到一个文件中。 
  制作一个指定扩展名文件的清单列表。
   
   思路:
   1,对指定目录进行递归。
   2,递归过程中,对文件指定指定条件的判断。
   3,将符合条件的文件进行存储。 
   4,将存储的符合条件的文件进行操作。比如将文件的绝对路径写到一个文件中。
public static void listDir(File dir, FilenameFilter filter, List<File> list) {
// 对指定目录进行遍历。
File[] files = dir.listFiles();


for (File file : files) {
if (file.isDirectory()) {// 如果是目录。
listDir(file, filter, list);// 递归
} else {
// 如果是文件,进行过滤器的过滤,将符合条件的进行集合的存储。
if (filter.accept(dir, file.getName())) {


list.add(file);
}
}
}
}


   序列流:
       SequenceInputStream:将流有序的排列.
       同时对多个源进行一起操作。
       原理:就是内部有一个有序的集合存储着这些读取流对象。
使用Vector有序集合存储流对象,因为Vector可以获取enumeration对象。
创建序列流对象,并接受枚举。
操作对象:ObjectOutputStream:可以操作对象的流对象。对象的持久化。
需求:将一个内存中的对象,写入到一个文件中。
类通过实现Serializable接口以启用其序列化功能。
ObjectInputStream:反序列化
序列化运行时使用一个称为。。。的版本号与每个可序列化的对象相关联。用来验证时否为同一个类。
不实现Serializable,就没有序列号。
实现了就要自定义一个序列号,UID号!
静态的数据是不会被序列化。
非静态的不想被序列化用关键字transient:转瞬即逝的。瞬态的transient

RandomAccessFile(随机访问文件):自身具备读写的方法。不是流体系中的成员。
特点:
1,随机访问。其实就是不断的改变指针的位置。从指定的位子进行读和写。
2,操作的是文件。
3,既能读,又能写。
4,该对象中维护了一个大型的字节数组,可以通过指针进行操作。
5,可以通过getFilePointer获取指针的位置,可以通过seek设置指针的位子。
6,该对象中维护了读取和写入的字节流。
   要想随机访问,必须要数据有规律。
RandomAccessFile ra = new RandomAccessFile("c:\\random.txt","rw");
如果文件不存在,则会创建,如果文件存在,不覆盖。
writeInt();保证字节原样性。
他可以对数据进行修改,而不覆盖文件。


管道流:PipedInputStream和PipedOutputStream。
输出输出可以直接进行连接,
    特点:
    1,输入流和输出流可以连接上。
    2,该流需要结合多线程技术,否则单线程容易死锁。
IO包的其他类。
操作基本数据类型:DataOutputStream
有个writeUTF()方法。可以指定UTF修改版编码解释数据。
    操作数组的流对象。
    ByteArrayInputStream   ByteArrayOutputStream  

---------------------- android培训java培训、期待与您交流! ----------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值