- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ------
1. 第二十二天回顾 File类,主要就是方法,但是没有操作文件,读写的能力,File必须和流对象配合。构造方法三种重载形式,两个静态常量;\平台无关性。mkdirs,exists,delete,getParent,getName,getParentFile,getAbsoluteFile,isDirectory,static ListRoots,listFiles需要你会写文件的过滤器。递归,方法自身调用,方法主体程序不变,方法参数在变化,可以考虑使用递归。实现了全目录的遍历
2. 第二十三天学习内容。File类删除目录,复制目录。打印流(装饰类),使用打印流替代转换流(OutputStreamWriter). 对象的序列化流ObjectInput(Output)Stream。集合IO的结合使用Properties(load,store)DateInputStream DateOutputStream基本数据类型读写
3. File类,递归删除目录
删除的步骤,进入目录,一层层向外删
实现了目录的全遍历,遍历的过程中,删掉文件和文件夹 delete,File构造方法中包装的路径,如果是文件,删除文件,如果是文件夹,删除文件夹
4. 复制目录 -- 会写出来
复制的是单级目录
数据源c:\\demo source File对象
数据目的 d:\\ target File对象
涉及到文件夹操作的采用File类实现
文件夹中的文件,IO流读写,字节流 字节数组缓冲
实现步骤:
l 在数据目的,创建一个和数据源同名的文件夹。获取到数据源文件夹名字。getName()--demo,创建d:\\demo. File类构造方法(File,String ) mkdirs创建
l 数据源有了,目的也有了,遍历数据源目录 listFiles()返回的是File数组,存储的是目录中的所有文件的全路径,获取数据源的文件名getName()
l 将数据目的d:\\demo和 文件名组合成新的File对象 构造方法(File,String)
l 字节流读写文件
5. 打印流对象
System.out 返回值结果PrintStream就是打印流
println()是PrintStream类的方法
PrintStream永远不会抛出IO异常,只操作数据目的,不操作数据源,添加功能到别的流对象。
打印流作用:日后凡是看到需要输出数据,优先选择打印流,Web开发,服务器使用打印流将数据打印到客户端浏览器。
第一个打印流是字节输出流PrintStream
第二个打印流是字符输出流PrintWriter,实现类PrintStream中的所有打印方法
PrintStream和PrintWrtier类的区别
共性:负责打印数据,不抛异常,不操作数据源,都有很多打印方法
区别:一个是字节流,一个是字符流,两个流的构造方法
PrintStream构造方法,传递的都是数据目的,接收File对象,字节输出流,字符串的文件名,三种类型参数
PrintWrtier构造方法,传递的都是数据目的,接收File对象,字节输出流,字符串的文件名,字符输出流,四种类型参数
使用打印流,将数据打印到目的地,由打印流的构造方法绝对
可以开启打印流的自动刷新功能,告别flush,构造方法中,如果参数是流对象的话就可以了,构造方法的参数上,加上true.
如果启用自动刷新,则必须调用三个方法,println,printf,format
6. 对象的序列化
将对象的数据写到文件中,序列化
把文件中保存的对象数据,读取,反序列化
写对象数据的流ObjectOutputStream
构造方法中,传递字节输出流OutputStream子类,FileOutputStream
写的方法voidwriteObject(Object obj)将对象中的数据,写入到字节输出流包装的文件
java.io.NotSerializableException:cn.itcast.iostream.Person,找API文档,在io包中发现了一个接口Serializable。实现Serializable接口的类,开启了序列化功能,如果不实现这个接口,无法序列化和反序列化
7. 对象的反序列化
将文件中保存的对象的数据读取出来,反序列化
读取对象数据的流ObjectInputStream
构造方法中,传递字节输入流InputStream子类,FileInputStream
读取对象的方法 ObjectreadObject() 读取文件中的对象,返回Object
抛出类找不到异常. 必须有class文件,否则不能实现
8. 序列化的静态问题
对象序列化,静态和对象有关系吗。
静态属于自己的类,不属于对象,因此静态不能序列化
成员变量,不定义静态,不想让他序列化
关键字,基础班最后关键字 transient,修饰符,用法非常单一,只能用在成员变量的修饰上,阻止变量序列化
9. Serializable接口的意义
接口特点,没有自己抽象方法,空接口
存在意义,称为标记型接口,就是在你的类上标记一下,JVM看到这个标记,可以进行序列化。
猪肉,紫色的戳子,意义检疫合格,准许销售上市
10. 序列化中的序列号问题
发生的过程java.io.InvalidClassException,写好了Person.java,编译生成class,进行了序列化。读取对象,一切正常。将Person.java中的原始代码进行了修改,肯定从新生成class文件,没有进行序列化,直接读取了序列化文件,此时出现了异常。就是序列号的冲突问题。
序列号冲突:Person.java文件的时候,生成class,class文件中就保存了这个类的序列号,此时对类进行了序列化操作,生成序列化文件person.txt,保存了一个序列号,这个号和class文件中的序列号是一致的。修改了Person.java源文件,将private修改成了public,从新编译class,序列号发生变化了,从新读取了序列化文件,此时的文件中保存的序列号和class文件中的序列号不一致,因此发生异常
序列号是怎么产生的:public static final在内存中,内存是否认识他们,不认识,只识别01010101010,编译的时候,javac 将这些修饰符翻译成内存识别的二进制,JVM就是根据class文件中的二进制,计算出的序列号
实现,修改源码后,不从新写文件,直接可以反序列化,直接读取,不出异常。前提:修改了源代码后,修改结果,不会影响的序列化和反序列化。
从新修改源代码后,不让JVM从新计算序列号,自己定义序列号
11. 集合IO的结合使用
集合使用的是Hashtable的子类Properties。存储键值对的集合,不能存储null,并且是一个线程安全的集合。两个自己的方法setProperty getProperty
IO读取文件的,IO读取文件,将文件中的键值对存储到集合,全自动
Properties类的方法load(字节或者字符输入流),文件中的键值对就会自动被存储到集合中
配置文件中,存储键值对的文件,不想要这个键值对,使用#注释
将集合中的键值对保存会原来的文件中,集合的方法store,传递字节或者字符输出流
12. 自定义方法,实现集合中的load功能
传递字节,字符的输入流,将文本中键值对,存储到集合
load方法本身,有2个重载形式,读取文件,存储集合
13. DataOutputStream写基本数据类型
继承OutputStream,字节输出流
构造方法中,传递字节输出流FileOutputStream
写基本数据类型的方法writeInt(int),将4个字节的int值写入输出流
14. DataInputStream读取基本数据类型
继承InputStream,字节输入流
构造方法中,传递字节输入流FileInputStream
读取基本数据类型的方法int readInt(),4个字节读取
文件末尾抛出EOFException,利用异常进行循环读取
15. 集合IO综合练习题
题目要求: 已知一个文本,保存的是学生的姓名,考试成绩
对成绩进行排序,成绩相同,按照姓名排,排序后的结果存储到新的文件中,文件的名字有要求,如果原始文件名字 score.txt 新生成排序后的文件sortScore.txt
分析:
文件读取方式,字符流,行读取
集合排序,读取到的姓名成绩存储到集合中,学生封装Student对象
使用哪一个集合List ,可以Collections
File获取原始文件名,改成新的名字,流对象将集合中的排序后的内容,写到文件中。File FileReader BufferedReader ArrayListCollections.sort,reverseOrder,打印流
16.