目录
- IO流简介
- 字节流
- 字节流的父类(抽象类)
- 字节节点流
- 字节过滤流
- 对象缓冲流ObjectOutputStream
- Serializable
- 字符编码
- 字符流
- 字符流父类(抽象类)
- 字符节点流
- 字符过滤流
- File类
- 筛选器的创建
- RandomAccessFile()
- 【TIPS】
IO流简介
通过数据流、序列化和文件系统提供系统输入和输出
流是内存与存储设备之间传输数据的通道
流是重要资源,用完及时关闭
位于java.io包下
流的分类:
按方向:
输入流:将《存储设备》的内容读入《内存》中
输出流:将《内存》中的数据存入《储存设备》
数据==>程序==>数据
按单位:(一切数据都是二进制)
字节流:以字节为单位,一个字节八位(视音频,图片都可以传输)
字符流:(两个字节,16位)只能处理字符。如果按字节来传递的话,同一个字节从一个地区传入另一个地区之后,因为编码的不同,会有不同的解释,此种情况直接传入字符。
按功能:
节点流:具有实际传输数据的读写功能
过滤流:在节点流的基础之上增强功能(过滤流又称为装饰类),单有过滤流无法传输数据,仅能起到锦上添花的功能。
字节流
字节流的父类(抽象类)
InputStream:字节输入流(所有字节输入流的超类)
OutputStream:字节输出流(所有字节输出流的超类)
直接继承Object
构造方法
OutputStream():仅有无参构造方法
InputStream():仅有无参构造方法
普通方法
public int read(){}
public int read(byte[] b){}
public int read(byte[] b, int off, int len){}
public void write(){}
byte[] bs = new byte[]{65,66,67};//定义byte数组,传入write方法中
public void write(bete[] b){};
public void write(byte[] b, int off, int len){};//鸡肋
字节节点流
FileOutputStream()
FileOutputStream():字节输出流OutputStream()的实现类
构造方法
FileOutputStream(String pathname);
fos.write()方法多次重复运行时,没有叠加效果,会覆盖之前内容
FileOutputStream(String s,boolean append);
append为true时,fos.write()方法多次重复运行时,有叠加效果,false则不会叠加
TIPS
1.FileOutputStream()的write()方法;会抛出IOException
2.FileOutputStream()没有无参构造方法
3.FileOutputStream()给的目标文件若不存在,fos.write()会自动创建文件。但是不能创建文件夹。
4.硬编码:写死了的代码
5.read()返回-1时表示文件已经读完
字节过滤流
BufferedOutputStream
BufferedInputStream 较为鸡肋
Buffer特性
1.提高IO效率,减少硬盘访问次数:Output时经过flush()才会将内容写入硬盘
数据写在缓冲区中,flush()是将缓存区的内容写入文件中,也可以直接close(),级联调用flush()
2.flush():将多次write()存在缓冲中数据一次性写入文件
构造方法
仅有两种:
BufferedOutputStream(OutputStream os)
BufferedOutputStream(OutputStream os, int size)
普通方法
flush();//刷新缓冲(将缓冲中的数据,一次性写入文件中,并清空缓冲区)
close(),级联调用flush()
【TIPS】
文件缓冲的大小,自己估计文件大小,自行定义大小
对象缓冲流ObjectOutputStream
把对象写到文件里,我们称为序列化
把对象读到内存中,我们称为反序列化
构造方法
1.protend ObjectOutputStream();//无参构造仅支持protend修饰的内容,子类
2.ObjectOutputStream(OutputStream os);
ObjectOutputStream oos = new ObjectOutputStream();
输出对象后不加flush会报错
普通代码
.writeDouble(3.5):将数据写入文件,而非文本
增强了缓冲区功能
增强了读写八种基本数据类型和字符串功能
增强了读写对象功能
readObject();从流中读取一个对象,读取到文件末尾的标志:java.io.EOFException
writeObject(Object obj);向流中写入对对象
案例代码
OutputStream os = new FileOutputStream("Files\\object.txt");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeDouble(3.5);
oos.flush();//不加这个flush会报错
InputStream is = new FileInputStream("Files\\object.txt");
ObjectInputStream ois = new ObjectInputStream(is);
double i = ois.readDouble();
Serializable
使用ObjectOutputStream类时需要对象实现Serializable
未实现Serializable的不可以实现序列化和反序列化
对对象进行序列化操作时,对象的所有属性都需要实现序列化接口
transient:修饰对象属性时,修饰的属性可以不具有序列化属性,不参与序列化
Serializable是标志性接口
字符编码
字符编码
ISO-8859-1
收录除ACSCII外,包括西欧,希腊,泰语,阿拉伯语的文字符号
UTF-8
针对Unicode可变长度字符编码
GB2312
简体中文
GBK
简体中文、扩展
BIG5
台湾,繁体中文
当编码方式和解码方式不一致时,会出现乱码
字符流
字符流父类(抽象类)
Reader
public int read(){}
public int read(char[] c){}
public int read(char[] c, int off, int len){}
Writer
public void write(int n){}
public void write(String str){}
public void write(char[] c){}
write():write支持缓冲,可以一次写入多个字符
flush():将文件一下子写入文件
字符节点流
FileReader
构造方法
FileReader(File file)
FileReader(char[] arr)
FileReader(String fileName)
普通方法
public int read(char[] c)
先创建字符数组,用于缓冲
char[] data = new char[4]:从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果到达文件的末尾,则返回-1
public void read(){}:从流中读取数据,每次读取一个,每一读取之后向后迭代一位,读完会返回-1
FileWriter
构造方法
FileWriter(String path);
FileWriter(String path,append mode);
没有无参构造方法
public void write(String str):一次写入多个字符
异常:IOException
字符过滤流
BufferedWriter
支持缓冲,支持换行(原生记事本不支持\n)
可以用普通方法:newLine();写入一个换行符
BufferedReader
readLine();一次读一行,读完以后返回null
通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。
PrintWriter(字符流):封装了print()/println()方法,支持写入后换行
桥转换流
InputStreamReader(字节流,编码格式)
OutputStreamWriter(字节流,编码格式)
可将字节流转换为字符流
可设置字符的编码方式
使用步骤
创建节点流
【创建过滤流,设置字符编码集】
封装过滤流
读写数据
关闭流
File类
File:文件和目录路径名的抽象表示形式,File对象代表一个文件和一个文件夹
文件具有文件名,修改时间,文件类型,只读,隐藏等等各种信息,因此需要用对象进行表示
File
File f = new File("文件路径"):虚拟的文件路径,将文件f和文件路径关联起来
f可以表示文件,也可以表示文件夹
需要通过f.creatNewFile()进行创建文件
构造方法
File没有无参构造器
File f = new File(String pathname);
方法
f.getName();//仅获取指定文件名本身,没有完整路径
public File getParentFile();//获取当前文件的父目录(文件对象)
boolean f.exiset();判断文件指定文件是否存在,返回值为Boolean类型
boolean f.creatNewFile();//通过File文件创建新文件,只能创建文件,不能创建文件夹。如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false
boolean f.mkdir();//创建文件夹,仅在上级文件夹存在的情况下能创建一层文件夹
boolean f.mkdirs();//创建多级文件夹
boolean f.canExetute();//文件是否可执行,可打开即表示可执行,不仅仅局限于.exe文件
boolean f.canRead();//文件是否可读
boolean f.canWrite();//文件是否可写
f.delete():删除此抽象路径指向的文件或文件夹,如果删除文件夹必须确保文件夹为空才可以删除。删除非空文件夹时不会报错,也不会删除
f.isFile();//当且仅当此抽象路径名表示的文件存在且是一个标准文件时,返回 true;否则返回 false
f.isDirectory();//当且仅当此抽象路径名表示的文件存在且 是一个目录时,返回 true;否则返回 false
f.getPath();返回的是创建文件对象时的路径
f.getAbsolutePath();//获取文件对象的完整全路径
f.getCanonicalPath();它和绝对路径类似,但是返回的是规范路径。
f.getParent();//获取文件的目录名(字符串)
long f.getTotalSpace();//返回当前盘符的字节数
long f.getUsabeSpace();//返回当前盘符的字节数
Long f.lastModified();//获取文件的最后修改时间,返回值为Long类型
String[] list = f.list();//获取指定文件夹下的文件名String数组
File[] file = f.listFiles();//获取文件夹内的文件对象数组
File[] files = f.listFiles(FileFilter);boolean accept()//筛选器
输出流就能创建文件
创建文件有IO异常
筛选器的创建
2.构建比较器
class MyFilter implements FileFilter{
public boolean accept(File file) {
}
}
字符串和文件对象可以相互转换
File f = new File(String path)
RandomAccessFile()
RandomAccessFile()://随机访问文件
文件指针:rat.getFilePointer()
构造方法:
RandomAccessFile(File file, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
1.write("".getBytes[]) and writeUTF()
same point and difference
2.write() and writeByte()
两行牛逼的代码
//字符输出:
PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream("infomations\\userInfo.properties", true), "UTF-8"));
//字符读入:
BufferedReader request = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
【TIPS】
1.在一个文件夹中,某个文件的名称和某个文件夹的名称不能相同
2.UUID.randomUUID()生成随机36位带有四个中划线的随机字符串,基本能保证创建字符串的唯一性。
3.class文件用字节流更好
4.PrintWriter类中的print(Object obj):输出时只是输入地址,不要求打印的对象实现序列化接口
字符流:操作文本
字节流:读写一切