1.文件的定义
文件就是保存数据的地方,有各种不同的类型比如pdf、mp4等
文件在程序中是以流的方式来操作:java程序(内存)读取磁盘文件叫输入流,java程序写入文件到磁盘叫输出流。
流:数据在数据源和程序之间经历的路程
java常用文件操作:
-new File(String , pathname) //根据路径构建一个File对象
-new File(File parent , String child)//根据父目录文件+子路径构建
-new File(String parent , String child)//根据父目录+子路径构建
等等
例子1:
例子2:
这里如果没有file.creatNewFile(),只有new的话File只是作为创建对象在内存中创建,并不会真正在磁盘中创建该文件。
例子3:
常用获取文件信息操作方法:
-file.getName()//得到文件名字
-file.getAbsolutePath()//得到文件绝对路径
-file.getParaent()//得到文件的父级目录
-file.length()//得到文件大小 ps:不同的文件编码方式会导致不同文件大小,比如UTF-8下英文字母占一个字节,中文占三个字节
-file.exists() //文件是否存在 file.isFile()//是不是一个文件 file.isDirectory()//是不是一个目录
常用目录操作以及文件删除
-file.delete()//删除file文件(或者目录) 返回布尔值 反应文件删除是否成功
-file.mkdir()//在file目录下创建一个目录 file.mkdirs()//创建一个多级目录
2. IO流原理及流的分类
I/O是Input/Output缩写,I/O技术是非常使用的技术,用于处理文件传输。如读/写文件,网络通讯等。
Java程序中对于数据的输入/输出操作以“流(stream)”的方式进行。
java.io包下提供了各种“流”类和接口,用于获取不同种类的数据,并通过方法输入输出数据。
输入input:读取外部数据(磁盘、数据库等)到程序(内存)中
输出output:将程序数据写入外部设备中
流的分类:
-字节流(8bit)二进制文件(视频、图片等)
-字符流(根据文件编码,一个字符等于多个字节,一般用于文本文件)
流的角色分类:
-节点流 ;-处理流/包装流
这里InputSream、Reader……四个类都是抽象类,不能直接创建,必须创建其子类。
IO流体系中常用的类:
1)字节流InputStream抽象类中常用的子类:
-FileInputStream:文件输入流
-BufferedInputStream : 缓冲字节输入流
-ObjectInputStream:对象字节输入流
文件流读取文件(输入流)例子:
这里注意:例子1使用流操作了之后一般需要在finally中关闭流。读取的异常一般是IO异常,这样可以兼容更多的异常。这段代码不能读取中文,因为中文是3个字节,这里的操作只能一个字节一个字节的读取,读取中文需要优化
优化使之能读中文:(说明:这里使用readLen使转String时读取正常)
读取结果:
这里第一次读了前8个字节,后面读了3个字节
字节流OutputStream抽象类中常用的子类:
-FileOutputStream:文件输出流
-BufferedOutputputStream : 缓冲字节输出流
-ObjectOutputStream:对象字节输出流
输出流例子:(outputStream对象的write方法)
写入字符串也可以这样:
说明:如果像上面这样创建,写入内容时会覆盖原来的内容,如果是要追加内容的话,输出流创建方式后面加一个参数即可:
字节输入输出流综合运用例子:图片文件的拷贝
操作完成后关闭流对象:
这里注意:程序访问C盘可能会出现权限错误,操作时改为其它磁盘即可
2)字符流:FileReader和FileWriter(使用时必须关闭(close)或者刷新(flush),不然无法写入)
例子 FileReader的使用-单个字符读取(结构与字节型的流差不多):
使用字符数组读取文件:
字符输出流FileWriter例子:
这里注意:finally里面没有关闭流或者刷新流,文件里面不会写入任何内容
字符数组写入:
3.节点流、处理流
节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
处理流(包装流)是“连接”已存在的流之上(不直接接触数据源),为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter
--为什么要有处理流:因为节点流一般操作直接操作数据,比较底层,效率可能没那么高,这时候java设计者就设计了处理流
处理流处理数据:在BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的只要是Readerd的子类即可,这样就会使其功能比较强大。同理BufferedWriter类中也有属性Writer,可以利用处理流对不同的节点流文件类型进行操作,灵活方便
包装流的这种设计模式叫修饰器设计模式
总结节点流和处理流的区别和联系:
-节点流是底层流,直接和数据打交道
-处理流是包装节点流,可以消除不同节点流的实现差异,也可以提供更加方便的方法来完成输入输出
-处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据原相连
处理流的功能主要体现在:
-性能的提高:主要以增加缓冲的方式来提高输入输出效率
-操作便捷:处理流可以提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
这里用BufferedReader以及BufferedWriter作为例子使用:
BufferedReader以及BufferedWriter属于字符流,是按照字符来读取数据的,不能去操作视频等二进制文件。
关闭时处理流,只需要关闭外层流(包装流)即可,因为实际在操作文件的还是处理流
BufferedReader的使用:
BufferedWriter的使用:
利用BufferedReader和BufferedWriter进行文件拷贝 :
字节处理流- BufferedInputStream、BufferedOutputStream
利用这两个处理流拷贝一个图片文件(视频文件也可):
对象流-ObjectInputStream、ObjectOutputStream
这个流看需求使用(能对数据类型和对象进行序列化和反序列化操作)
-将int num = 100 这个数据保存在文件中而非100数字,并且要求能恢复成int 100
-将一些对象保存在文件中并且能够从文件恢复
简单的保存值的操作不能称为序列化
序列化和反序列化:
-序列化就是在保存数据时,保存数据的值和数据类型
-反序列化就是在恢复数据时,恢复数据的值和数据类型
-需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现Serializable或 Externalizable接口
-序列化的类一般选择实现Serializable接口因为这是一个标记接口,标记接口-里面没有任何需要重新实现的方法
ObjectInputStream、ObjectOutputStream的各类接口关系:
使用案例:使用ObjectOutputStream完成一个对象的序列化
注意:这里的.dat是任取的,保存序列化文件打开一般都是乱码
使用ObjectInputStream对一个对象的反序列化恢复数据:
注意读写文件细节说明:
-读写顺序要一致
-要求序列化或反序列化对象,需要实现Serializable
-序列化的类建议添加SerialVersionUID为了提高版本兼容性(就是在类里添加一个private static final SerialVersionUID的值,这样的化如果序列化的类进行了普通属性的修改,则java不会认为这是一个新类,而是只认为其进行了一个版本的变更)。
-序列化对象时,默认将对象的所有属性都序列化,但除了static或transient修饰的成员
-序列化对象时,要求里面的属性(其它类)的类型也需要实现序列化接口
-序列化具备可继承性,也就是如果某某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
4. 输入流、输出流
标准输入输出流 InputAndOutput.java
System.in InputStream类型 默认设备是键盘
System.out PrintStream类型 默认设备是显示器
标准输入
System类的public final static InputStream in = null
System.in的编译类型是InputStream 运行类型是BufferedInputStream
标准输出
System类的public final static PrintStream out = null
System.out的编译类型是PrintStream,运行类型是PrintStream
System.out.println就是调用out对象将数据输出到显示器
Scanner扫描器对象里面就是标准输入流System.in
转换流transformation – InputStreamReader和OutputStreamWriter
-默认情况下是按UTF-8编码进行读取写入字符,如果编码格式不一致,读取或写入的操作很有可能就会是乱码。我们应该在字节流转换成字节流的时候定义好编码,这里就要用到转换流。
输入转换流里有一个最重要的初始化方法,传入 一个字节流 和 一个编码方式
应用案例:将字节流转换成字符流,对文件进行读取,进而包装成BufferedReader
应用案例:输出转换流
打印流 – PrintStream和PrintWriter 只有输出流 没有输入流
根据PrintStream的几种初始化方法,可以选择将内容打印到屏幕也可以输出到文件
5. Properties类
配置文件:mysql.properties
1.传统方式
小修改一下:
假如以后项目中IP这样的信息非常多,那么传统方式就会非常繁琐
2.使用properties类实现
Properties类介绍:
-专门用于读写配置文件的集合类
配置未见格式:
键=值
键=值
-键值对不需要有空格,值不需要用引号括起来,默认类型是String
常用方法:
读取:
修改与创建:
Ps:
-这里setProperties如果有这个key就是修改,没有就是创建
-这里“汤姆”会被存为unicode码
-这里store第二个参数null代表没有注释,有注释直接加字符串即可
-Properties的父类是HashTable 核心代码就是HashTable