I/O流
1. I/O是一类很大的框架,Java为了方便管理,将有关I/O操作的类全都放到了java.io.*包下。流的本质也是对文件的处理。
2. File类提供管理文件或目录的方法。File实例表示真实文件系统中的一个文件或者目录。但是File只能设置和获取文件本身的信息,不能设置和获取文件内部的内容。
3.java提供了十分详细的文件处理方法:
——构造方法
File(String pathname): pathname表示文件路径或者目录路径;
File(String parent, String child): 参数parent表示根路径,参数child表示子路径;
File(File parent, String child): 参数parent表示根路径,参数child表示子路径;
——普通方法
boolean createNewFile():创建一个新的文件,如果文件已经存在,则创建失败(返回false),否则创建成功(返回true)。
boolean delete():删除文件或者空目录
boolean mkdir()/mkdirs():创建一个或者多个目录(连续创建),如果该目录的父目录不存在话,那么还会创建所有的父目录;
boolean renameTo(File destination):如果路径名相同就改名、如果路径名不相同就移动并改名
boolean canRead()/canWrite():判断指定的文件是否能读取或者写入数据
boolean exists():判断指定的文件或者目录是否存在
String[] list():返回指定目录下所有文件名或者子目录名所组成的字符串数组
long lastModified():返回指定文件最后一次被修改的时间(从1970年1月1日凌晨12点到这个文件的修改时间之间所经历的毫秒数)
String getPath()/getAbsolutePath():返回指定文件或者目录的路径和绝对路径
String getCanonicalPath(): 获取该File对象所代表的文件或者目录的正规路径
String getParent()/getName():返回指定文件或者目录的父目录(没有返回null)和名字
4.——I/O流
程序的主要任务是操纵数据。在Java中,把一组有序的数据序列称为流。
根据操作的方向,可以把流分为输入流和输出流两种。程序从输入流读取数据,向输出流写出数据。
根据读写数据的单位划分,可以分为字节流和字符流。
根据功能划分:可以分为节点流和包装流。
——I/O中的四大基类:字节输入流(InputStream);字节输出流(OutputStream);字符输入流(Reader);字符输出流(Writer);
四大基类都是抽象类,其他流都是继承自四大基流,我们不能创建四大基流的对象,只能创建其子类对象。
——操作I/O的基本流程
1、创建源或者目标对象
输入操作:把文件中的数据读取到java程序中,此时文件是源,程序是目标。
输出操作:把程序中的数据写入到文件中,此时文件是目标,程序是源。
2、创建IO流对象
输入操作:创建输入流
输出操作:创建输出流
3、具体的IO操作(read()/write())
输入操作:调用输入流中的read()方法
输出操作 :调用输出流中的write()方法
4、关闭资源:close()方法,不要忘掉,无论什么流,都有close(),用来关闭资源 。
选择字节流/字符流的情况:
如果现在的文件是一个二进制文件(图片,视频,音频等),操作的时候就必须用字节流读取。
如果文件是一个文本文件,最好用字符流去读(也可以用字节流去读,但效率低)。一个字符可以表示一个汉字。
注意:使用字节流操作汉字或特殊的符号语言的时候,可能会出现乱码,建议使用字符流。
——文件过滤器
FilenameFilter:实现此接口的类实例可用于过滤器文件名;
——包装流(处理流)
1、隐藏了底层的节点流的差异,并对外提供了更方便的输入/输出功能,让我们只关心高级流的操作;
2、使用处理流包装了节点流,程序直接操作处理流,让节点流与底层的设备做IO操作;
3、只需要关闭包装流即可;
new 包装流(节点流对象)
其实包装流源码中隐藏了一种设计模式——装饰设计模式。
使用处理流的优势:
1、使用处理流进行输入输出操作更简单;
2、使用处理流的执行效率更高;
——缓冲流:是一个包装流,目的起缓冲作用;
BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter
int read():每次都从磁盘文件中读取一个字节. 直接操作磁盘文件性能极低.解决方案是:定义一个数组作为缓冲区.byte[] buffer = new byte[1024]; 该数组其实就是一个缓冲区。一次性从磁盘文件中读取1024个字节。如此以来,操作磁盘文件的次数少了,性能得以提升。缓冲流自带一个缓冲区,默认大小8192,并且该大小可以手动设置,不过一般我们不会手动设置。
——转化流
只能把字节流转换成字符流;
InputStreamReader:把字节输入流转换成字符输入流
OutputStreamWriter:把字节输出流转换成字符输出流
为什么没有字符流转成字节流?
答:任意一个文件都可以通过字节流去读取,而文本文件通过字符流读取,从某种层面上说,字节流比字符流应用范围更广。转换流在网络编程里会用到,字节流读取效率低。
——数组流(内存流)(了解):把数据先临时存在数组中,待会儿再从数组中获取出来。
——合并流(顺序流): 把多个输入流合并成一个流对象:SequenecInputStream
——打印流: 打 印流只能是输出流。
序列化和反序列化
瞬态:transient(可以存隐私的内容,取得时候显示默认值,不会显示真正的值)
1、如果某些数据不需要被序列化怎么办?
瞬态的字段是不能被序列化的——transient
2、序列化版本问题
反序列化Java对象时必须提供该对象的class文件,现在问题是,系统中的class文件也会升级,如何保证两个class文件的兼容。
如果不显示的定义serialVersionUID类变量,该类变量的值由JVM根据类的相关信息来计算,而修改后的类的计算方法和之前的往往不同。从而造成了对象序列化因为版本不兼容二失败。