IO流
处理设备之间的数据传输
按照方向分:输入流,输出流(相对于内存)
按照操作的数据分:字节流,字符流
按照角色分:节点流,处理流
字节流:
可以处理任何类型的数据,音频,视频,图片,文本
编码:ASCII,ISO8859-1(欧洲编码),GBK,UTF-8
以Stream结尾
字节输入流父类:InputStream
字节输出流父类:OutputStream
字符流:
基于字节流,在字节流的基础上融入了编码
专门处理文本的
字符输入流父类:Reader
字符输出流父类:Writer
根据设备选取对应的子类
节点流:
向一个特定的IO设备读写数据的流
程序直接连接到实际的程序源,和实际的输入输出节点连接
处理流:
对一个已存在的流进行连接或封装,通过封装后的流来实现读写功能
Writer:
1 创建文件输出流对象,并绑定文件
文件不存在会自动创建
文件存在会被覆盖
2 使用文件输出流对象向文件写入数据
write()
此时没有写入到文件,写入到流中,流内部有一个字节数组,因为要查表
flush()把流中的数据刷到文件中
刷完之后可以继续写入
3 关闭输入流,同时会刷新流中的数据到文件中
close()
文件续写:
FileWriter(fileName, isAppend)//是否在fileName中追加数据
System.getProperty("line.separator");//获得系统换行的关键词
Reader:
1 创建文件输入流对象,并绑定文件
被读取的文件必须事先存在
2 读取
read()读取单个字符
一次读一个,返回字符编码
读到文件末尾,返回-1
3 关流
文件复制:
读取被复制的文件
把读出来的数据写入到一个新的文件
缓冲流:
缓冲流:
缓冲流不具备读或写的功能
只是提高了数据读或写效率
使用缓冲流必须结合读流或写流
将被提高效率的写入流对象作为参数传递给缓冲流的构造方法
BufferedWriter:
write():写入到缓冲流的内部缓冲区
newLine():添加一个行分隔符,跨平台的写入换行的功能
BufferedReader:
readLine():一次读取一行
不包含最后的换行符
String line = null;
while((line = br.readLine()) != null)
{
System.out.println(line);
}
装饰设计模式:
基于已经存在的功能提供增强功能
解决某一类问题最便捷的方式
装饰设计模式的好处:
1 简化了原有体系
2 装饰类还属于原体系
eg:
BufferedReader
LineNumberReader
FileWriter: writer()
FileReader: int read() int read(char[])
BufferedWriter: newLine()
BufferedReader: readLine()
InputStream:
getBytes():编码
available():返回文件总大小
文件小时创建的数组和文件大小相同,可以只读一次,不需要循环
文件过大时不适合
FileInputStream fis = new FileInputStream("ss.txt");
//创建一个长度为1024的容器
byte[] arr = new byte[fis.available()];
//实际读取的字节数
int num = 0;
while((num = fis.read(arr)) != -1)
{
System.out.print(new String(arr, 0, num));
}
OutputStream:
System.in:标准的输入
InputStream in = System.in;
和键盘设备关联在一起的字节输入流对象
int num = in.read();//阻塞式方法
System.out:标准的输出
转换流:
指定编码
InputStreamReader:将字节流转成字符流
OutputStreamWriter:
System.setIn():改变标准的输入
System.setOut():改变标准的输出
File:
文件过滤器:
FilenameFilter接口:
重写accept(File dir, String name)方法
对指定的dir进行迭代
Properties:
是一个map集合
存储的是属性
属性名和属性值必须都是字符串类型
所以没有使用泛型
可以和流使用的集合
Properties pro = System.getProperties();
//System.out.prinln(p);
pro.list(System.out);
打印流:
字节打印流:printStream
可以使用OutputStream的功能,增加了打印功能
可以操作的目的:
字符串类型的文件名
File类型的文件
字节输出流
字符打印流:printWriter
可以使用Writer的基本功能,增加了打印功能
可以操作的目的:
字符串类型的文件名
File类型的文件
字节输出流(可以自动刷新)
字符输出流(可以自动刷新)
合并流:(序列流)
序列化和反序列化:(对象流)
序列化:存储对象
ObjectOutputStream:
标记接口:Serializable
实现该接口无需实现任何方法,它只是表明该类的实例是可序列化的
序列化的时候同时生成一个serialVersionUID来标记进行序列化的类
反序列化:读取对象
ObjectInputStream:
ClassNotFoundException异常:
找不到序列化对象的类
InvalisClassException异常:
即类的serialVersionUID不同
建议自己声明serialVersionUID
transient:瞬态
修饰的成员不参与序列化
如果文件中有若干个对象,使用对象读取流ois.readObject()时如何判读到结尾?
1.将若干对象装入一个容器,然后将容器送入一个对象写入即可,读取时,只要读取一个对象即可
2.可以直接使用EOFException来判断结束
public static void main(String[] args) throws IOException, ClassNotFoundException
{
CompareByAge com = new CompareByAge();
TreeSet<Person> set = new TreeSet<>(com);
set.add(new Person("张三",90));
set.add(new Person("李四",19));
set.add(new Person("王五",93));
set.add(new Person("赵六",92));
set.add(new Person("分期",19));
Iterator<Person> ite = set.iterator();
while(ite.hasNext())
{
System.out.println(ite.next());
}
writeToFile(set);
}
public static void writeToFile(TreeSet<Person> set) throws IOException, ClassNotFoundException
{
//使用对象流将集合写入test.txt文件中
FileOutputStream fos = new FileOutputStream(new File("D:\Test\test.txt"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
Iterator<Person> ite = set.iterator();
while(ite.hasNext())
{
oos.writeObject(ite.next());
}
oos.close();
FileInputStream fis = new FileInputStream(new File("D:\Test\test.txt"));
ObjectInputStream ois = new ObjectInputStream(fis);
try{
while(true)
{
Person person = (Person)ois.readObject();
System.out.println("******:"+person);
}
}catch(EOFException e)
{
//已从流中读完
}finally
{
ois.close();
}
}
RandomAccessFile:
随机访问文件
不属于io体系,只能访问文件
内部既有字节输入流,也有字节输出流(既可以读也可以写)
内部有一个字节数组,使用指针操作该数组,从而实现的随机访问
数据流:
操作基本数据类型:
DataOutputStream:
DataInputStream:
内存流:
ByteArrayOutputStream:
向内存中写
ByteAarrayInputStream:
从内存中读
内存流不需要close()
编码和解码:
编码:
byte[] getBytes():
使用平台的默认字符集将此String编码为byte序列,并将结果存入一个新的byte数组中
byte[] getBytes(CharSet chaeser):
使用给定的charset将此String编码到byte序列,并将结果存储到新的byte数组中
解码:
String(byte[] bytes):
通过平台的默认字符集解码指定的byte数组,构造一个新的String
String(byte[] bytes, Charset charset):
通过指定的charset解码指定的byte数组,构造一个新的String
编码编对了,解码肯定能解对
编码编错了,不能解对了