大家好,又见面了,我是你们的朋友全栈君。
【I/O流】 Input/Output:输入输出机制 输入机制:允许java程序获取外部设备的数据(磁盘,光盘,网络等)。 输出机制:保留java程序中的数据,输出到外部设备上(磁盘,光盘等)。
【可以看出,IO的入出是以java程序为第一人称的】
IO各种之间的关系
先看张图:
流的分类: 通过不同的方法,可以对于进行分类。 1.按照功能来划分: 输入流:只能从中读取数据,而不能向其写入数据。 输出流:只能向其写入数据,而不能从中读取数据。 2.按照处理单元来划分 字节流和字符流操作的方式基本上完全相同。操作的数据单元不同 字节流:操作的是8位的字节 InputStream/OutputStream 作为字节流的基类 字符流:操作的是16位的字符 Reader/Writer 作为字符流的基类 3.按照角色进行划分 节点流:可以直接从/向外部设备读取/写入数据的流,称之为节点流,节点流也被称之为低级流。 处理流:对于已经存在的流进行了连接和封装,扩展了原来的读/写的功能。处理流也被称之为高级流。
java的io包当中包括40多个流,他们都有紧密的联系,和使用的规律,这些流都源于4个抽象基类。
InputStream / Reader :所有的输入流的基类,前者是字节输入流,后者是字符输入流。 OutputStream/Writer :所有输出流的基本,前者是字节输出流,后者是字符输出流。
流的操作步骤:
文件字节输入流读取文件内容的步骤: * 1.创建流对象 * 2.创建一个缓存字节的容器数组 * 3.定义一个变量,保存实际读取的字节数 * 4.循环读取数据 * 5.操作保存数据的数组 * 6.关闭流
public class FileInputStreamDemo01 {
public static void main(String[] args) {
File file = new File("C:\\Users\\Administrator\\Desktop\\2017-08-16\\2017-08-16.java");
// 1.创建流对象
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
// 2.创建一个缓存字节的容器数组
byte[]buf = new byte[1024];
// 3.定义一个变量,保存实际读取的字节数
int hasRead = 0;
// 4.循环读取数据
// while (true) {
// hasRead = fis.read(buf);
// if (hasRead==-1) {
// break;
// }
//// 5.操作保存数据的数组
// String msg = new String(buf, 0,hasRead);
// System.out.print(msg);
// }
while ((hasRead = fis.read(buf))!=-1) {
String str = new String(buf,0,hasRead);
System.out.print(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
// 6.关闭流
if (fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件字节输出流写入文件内容的步骤: * 1.选择流:创建流对象 * 2.准备数据源,把数据源转换成字节数组类型 * 3.通过流向文件当中写入数据 * 4.刷新流 * 5.关闭流
public class FileOutputStreamDemo01 {
public static void main(String[] args) {
// 1.选择流:创建流对象
FileOutputStream fos =null;
try {
fos = new FileOutputStream(new File("c:\\read.txt"),true);
// 2.准备数据源,把数据源转换成字节数组类型
// String msg = "春夜喜雨\n好雨知时节,当春乃发生。\n随风潜入夜,润物细无声。";
String msg = "\n野径云俱黑,江船火独明。\n晓看红湿处,花丛锦官城。";
byte[] data = msg.getBytes();
// 3.通过流向文件当中写入数据
fos.write(data, 0, data.length);
// 4.刷新流
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos!=null) {
// 5.关闭流
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
处理流的好处: 处理流必须在节点流的基础之上,增加了效率,提高了性能,扩大的功能。 如图:
1.缓冲流
2,转换流:
转换流作用:把字节流转换成字符流,可以解决出现的因为编码集和解码集造成的乱码问题。 * InputStreamReader: * OutputStreamWriter: * 编码:字符—–编码字符集——–》二进制 * 解码:二进制—解码字符集———》字符 * 在处理文件时,如果文件的字符格式和编译器处理格式不一样时,会出现乱码问题。比如文件字符格式GBK, * 而编译器是UTF-8格式,那么就会产生该问题。 * * 出现乱码问题的原因: * 1.编码和解码字符集不一致造成了乱码 * 2.字节的缺失,长度的丢失 * * 大部分情况下,出现乱码问题是因为中国汉字,因为中国汉字在不同的字符编码当中占据的字节数不相同,但是都占据多个字节。 * 而英文字母没有这个问题,因为英文字母在所有的字符编码当中都占据一个字节。 InputStreamReader :转换输入流–》将字节输入流转换成字符输入流 作用:为了防止文件使用字符输入流处理时出现乱码问题。
节点流:
字节数组流(内存流) ByteArrayInputStream ByteArrayOutputStream 因为内存输出流当中又新增的方法,不能使用多态,不能够让父类的引用指向之类的对象。 作用:可以在循环当中把所有的数据存放到统一的容器当中,然后在循环结束之后可以把容器当中所有的内容一起取出来。 注意事项: 内存流属于内存当中的资源,所以数据量不要过大,如果太大,会造成内存溢出的错误。
数据处理流:
DataOutputStream DataInputStream 特点: 既能够保存数据本身,又能够保存数据类型(基本数据类型+String)
序列化流:
将对象转换成字节序列的过程,就是对象序列化过程。 * 将字节序列恢复为对象的过程称之为对象的反序列化。 * * 作用:保留对象(引用数据类型数据的)类型+数据。 * * 序列化流 :输出流 ObjectOutputStream writeObject() * 反序列化流: 输入流 ObjectInputStream readObject() * * 注意事项: * 1。先序列化然后在反序列化,而且反序列化的顺序必须和序列化的顺序保持一致。 * 2.并不是所有的对象都能够被序列化。只有实现了Serializable接口的类的对象才能够被序列化。 * 对象当中并不是所有的属性都能够被序列化。 * * 对象序列化的主要用途: * 1.把对象转换成字节序列,保存到硬盘当中,持久化存储,通常保存为文件。 * 2.在网络上传递的是对象的字节序列 * * 对象序列化的步骤: * 1.创建对象输出流,在构造方法当中可以包含其他输出节点流,如文件输出流。 * 2.把对象通过writeObject的方式写入。 * * 对象反序列化的步骤: * 1.创建对象输入流,在构造方法当中可以包含其他的输入节点流,如文件输入流 * 2.通过readObject()方法读取对象。
serialVersionUID :序列化版本id * 作用:从字面角度看,就是序列化版本号。凡是实现了Serializable接口的类, * 都会有一个默认的静态的序列化标识。 * * 1.类在不同的版本之间,可以解决序列化兼容问题,如果之前版本当中在文件中保存对象, * 那么版本升级后,如果序列化id一致,我们可以认为文件中的对象依然是此类的对象。 * * 2.如果类在不同的版本之间不希望兼容,但是还希望类的对象能够序列,那么就在不同版本中 * 使用不同的序列化id。 * * transient :当类中有属性不想被序列化,那么就使用这个修饰符修饰。
File类:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/125265.html原文链接:https://javaforall.cn