File类
win中的路径需要用\\
概述
java.io.File
类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作
构造方法
- public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
- public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
- public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。
注意:
- 一个File对象代表硬盘中实际存在的一个文件或者目录。
- 无论该路径下是否存在文件或者目录,都不影响File对象的创建。
获取功能的方法
- public String getAbsolutePath() :返回此File的绝对路径名字符串。
- public String getPath() :将此File转换为路径名字符串。构造方法写的什么返回的就是什么
- public String getName() :返回由此File表示的文件或目录的名称。
- public long length() :返回由此File表示的文件的长度。只能查看单个文件的长度。不能直接查看文件夹的大小
判断方法
- public boolean exists() :此File表示的文件或目录是否实际存在。
- public boolean isDirectory() :此File表示的是否为目录。
- public boolean isFile() :此File表示的是否为文件。
创建删除功能的方法
- public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
- public boolean delete() :删除由此F ile表示的文件或目录。
- public boolean mkdir() :创建由此File表示的目录。只能创建一级目录
- public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。能创建多级目录
API中说明:delete方法,如果此File表示目录,则目录必须为空才能删除
目录的遍历
- public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
- public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
如果目录不存在,返回null。目录里面没内容,返回空列表。所以在遍历之前,看看是不是空指针。
IO流
IO流分类
字节流:所有一切都是字节流
字符流:只能操作纯文本,不能操作其他文件
输入流 | 输出流 | |
---|---|---|
字节流 | 字节输入流InputStream | 字节输出流OutputStream |
字符流 | 字符输入流Reader | 字符输出流Writer |
OutputStream(字节输出流)
java.io.OutputStream
抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字
节输出流的基本共性功能方法。抽象类不能创建对象,需要使用子类。
常用方法
- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
- public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输
出到此输出流。 - public abstract void write(int b) :将指定的字节输出流。
close方法,当完成流的操作时,必须调用此方法,释放系统资源。
常用子类
FileOutputStream类:文件字节输出流,向文件中写字节。
构造方法(常用)
- public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
- public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文
件,会清空这个文件的数据。
字符串变成字节数组:public byte[] getBytes()
踩坑记录:
FileOutputStream不能在不存在的文件路径写,比如说不存在的文件夹下面
续写以及换行写入
每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能
继续添加新数据呢?
- public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的
文件。 - public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。
回车符 \r 和换行符 \n :
回车符:回到一行的开头(return)。
换行符:下一行(newline)。
系统中的换行:
Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
Unix系统里,每行结尾只有 换行 ,即 \n ;
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
InputStream(字节输入流)
java.io.InputStream
抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入
流的基本共性功能方法。抽象类不能创建对象,需要使用子类。
常用方法
- public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
- public abstract int read() : 从输入流读取数据的下一个字节。返回的是读到的字节
- public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。返回的是读取字节的数量。且每次最大的读取字节个数是b的长度
close方法,当完成流的操作时,必须调用此方法,释放系统资源。
常用子类
java.io.FileInputStream
类是文件输入流,从文件中读取字节。
构造方法(常用)
- FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系
统中的 File对象 file命名。 - FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件
系统中的路径名 name命名。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出 FileNotFoundException
。
字节数组变成字符串:public String (byte[] bs)
理用的是String的构造方法
字节流读取中文的问题
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为
一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文
件。但是,如果你不把他输入到控制台来看,其实也不会有什么问题。
Reader(字符输入流)
java.io.Reader
抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。
常用方法
- public void close() :关闭此流并释放与此流相关联的任何系统资源。
- public int read() : 从输入流读取一个字符。遇到EOF返回-1
- public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中。每次读取的长度跟字符数组的长度有关。返回的是读取的个数。
常用子类
java.io.FileReader
类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
注意:
- 字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。
idea中UTF-8- 字节缓冲区:一个字节数组,用来临时存储字节数据。
构造方法(常用)
- FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
- FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
Writer(字符输出流)
java.io.Writer
抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。
常用方法
- public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
- public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
- public void write(int c) :写出一个字符。
- public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
- public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量
off开始输出到此输出流。 - public void write(String str) :写出一个字符串。
- public void write(String str, int off, int len) :写出一个字符串的指定部分
常用子类
java.io.FileWriter
类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
构造方法
- FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
- FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
- public FileWriter(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的
文件。boolean类型的值, true 表示追加数据, false 表示清空原有数据。 - public FileWriter(String name, boolean append) : 创建文件输出流以指定的名称写入文件。boolean类型的值, true 表示追加数据, false 表示清空原有数据。
当创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。
相关方法
字符串转换为字符数组字符串.toCharArray()
flush和close
字节流内部没有缓冲区,只要调用write方法,就是写出到目的地,所以不关流,也不会丢失数据。
字符流内部有缓冲区,调用write方法,先写到缓冲区,如果缓冲区数据满了,会自动刷新到目的地,如果没有执行关闭流的操作,会导致缓冲区可能还会有数据,程序停止后,数据就会丢失。备注:查看源代码,缓冲区是1024个字节
- flush :刷新缓冲区,流对象可以继续使用。
- close :关闭流,释放系统资源。关闭前会刷新缓冲区。
IO的异常处理
throws:声明抛出异常,交给调用者处理
try-catch:自己来处理
但记着一定要close,即finally里面一定要调用close。以及不要把要io对象在try中定义,因为加了一个大括号后,就变成了在一个大括号中的局部变量,需要在try这个大括号以外进行声明(提升作用域)。另外在finally中,close方法也会有异常,需要两个分开处理。因为如果两个写在同一个try中,如果第一个close有异常,第二个close就不会执行。
JDK1.7之后:
属性集(Properties类)
java.util.Properties
继承于 Hashtable
,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其
对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时, System.getProperties
方法就是返回
一个 Properties 对象。格式:属性名=属性值
- Properties类是Map集合的实现类,Map中定义的方法,都有
- Properties类继承Hashtable<K,V>时,已经确定了K的类型:Object,V的类型:Object。所以Properties类没有泛型,创建Properties类的对象时,不能指定泛型
- Properties类是唯一一个和IO流结合使用的双列集合
构造方法(部分)
public Properties() :创建一个空的属性列表。
特有方法
与获取值相关的
- public Object setProperty(String key, String value) : 保存一对属性(保存一个键值对,等价于map中的put方法)。
- public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
- public Set
stringPropertyNames() :所有键的名称的集合。
与IO流相关的
- public void load(InputStream inStream) : 从字节输入流中读取键值对。其实是将文件的属性按键值对呈现出来
- public void load(Reader r) :把子类FileReader对象关联的源文件中的内容,以键值对的方式,加载到Properties中。
注意:
- Properties集合加载的文件,建议拓展名写
.properties
- .properties中的内容,一个键值对占一行,格式:键=值
读取Properties文件的快捷方式
java.util包中的resourcebundle
使用方法:
ResourceBundle rb = ResourceBundle.getBundle("redis")
注意这里不用写后缀名,因为这个类专门读properties文件
调用方法
rb.getString("键名")就能读到相应值,返回类型为字符串
缓冲流
缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
- 字节缓冲流: BufferedInputStream , BufferedOutputStream
- 字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是 在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。(按我的理解,说白了就是一个包装流)
字节缓冲流
内部定义了定义了一个长度为8192长度的数组
构造方法
- public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
- public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
常用方法
- public void close(): 关闭流,释放资源
- public void write(int b): 写出一个字节的
- public void write(byte[] bs): 写出一个字节数组的
- public void write(byte[] bs,int off,int len): 写出一个字节数组的一部分
- public int read(): 读取一个字节
- public int read(byte[] bs):读取一些字节,把读取到的多个字节的内容,存储到方法参数字节数组bs中
参数:
byte[] bs: 字节数组
int off: 起始索引
int len: 写出字节的个数
注意事项
- 对于缓冲流,不要自己调用flush方法
- 只需要关闭缓冲流,缓冲流内部的IO流会自动关闭
字符缓冲流
构造方法
- public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
- public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
常用方法
- public void close(): 关闭流释放资源
- public void write(int ch): 写出一个字符
- public void write(char[] chs): 写出一个字符数组
- public void write(char[] chs,int index,int len): 写出一个字符数组的一部分
- public void write(String str): 写出一个字符串
- public void write(String str,int index,int len): 写出一个字符串的一部分
- public int read(): 读取一个字符
- public int read(char[] chs):读取一些字符,把读取到的一些字符存入到方法参数字符数组chs中,返回的是读取的字符的数量。遇到文件结束标志,返回-1,说明读取文件应该结束了。
特有方法
- public String readLine() : 读取一行文本,遇到文件结束标志: 返回null。读取到的一行文本的内容,不包含换行符,遇到换行符,说明这一行结束了。遇到文件结尾,返回null
- public void newLine():写入一行分隔符(换行符),自适应系统
转换流
如何获取String的指定编码格式的字节内容? 编码
String类的成员方法 public byte[] getBytes(): 根据平台默认编码表(IDEA默认编码表: UTF-8),获取String的字节数组 public byte[] getBytes(String charsetName) : 根据方法参数指定的编码表,获取String的字节数组 参数: String charsetName: 编码表的名称 常用的编码表 GBK/UTF-8
如何把字节数组,按照指定编码格式,转换成String 解码
String类的构造方法 public String(byte[] bs): 根据平台默认编码表(IDEA默认编码表: UTF-8),把构造方法参数中指定的字节数组,转换成String
public String(byte[] bytes, String charsetName):
根据构造方法指定编码表,把构造方法参数中指定的字节数组,转换成String
InputStreamReader类
转换流 java.io.InputStreamReader
,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定
的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法
- InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
- InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。
OutputStreamWriter类
构造方法
- OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
- OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。
序列化
Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 、 对象的
类型 和 对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。存储的是对象的完整的字节内容
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。 对象的数据 、 对象的类型 和 对象
中存储的数据 信息,都可以用来在内存中创建对象。
总结:
序列化:把对象写入到文件
注意
在对对象进行序列化操作之前,需要实现Serializable接口来启用序列化功能
ObjectOutputStream类
构造方法
public ObjectOutputStream(OutputStream out)
: 创建一个指定OutputStream的ObjectOutputStream。
常用方法
public void writeObject(Object obj) : 将指定的对象写入 把方法参数obj写入文件
ObjectInputStream类
ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。
构造方法
public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。
常用方法
public Object readObject() : 将指定的对象写入 把方法参数obj写入文件
注意事项
静态和瞬态不能序列化
静态:加了static的变量不能被序列化,因为静态是属于类
瞬态:被transient的内容也不能被序列化
序列号冲突异常
当类实现Serializable接口后,在编译时会根据类的成员变量计算一个long类型数字(序列号),被保存在.class文件当中,当序列化对象时,同事在储存对象的文件中,也保存一份序列号。
只要修改类的成员,序列号就会重新计算。
当进行反序列化时,从文件中读取对象,会用文件中的序列号和.class文件中的序列号做对比,如果不一致,爆出序列号冲突异常
解决方案:
手动指定固定的序列号,这样不管怎么修改,就不会修改序列号
例如
public class Employee implements java.io.Serializable {
// 加入序列版本号,其中权限修饰符可以是任意的,但static,final,long,serialVersionUID这四个是固定的,后面的 //值可以自己设定
private static final long serialVersionUID = 1L;
public String name;
public String address;
// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
public int eid;
public void addressCheck() {
System.out.println("Address check : " + name + " -- " + address);
}
}
打印流
平时我们在控制台打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于java.io.PrintStream
类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。
PrintStream类
构造方法
public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流。
特有方法
print(xxx):原样输出
println(xxx):原样输出