java IO 流
按代为分
字节流: 以字节为单位, 可以读写所有数据.
字符流: 以字符为单位, 只能读写文本数据.
按功能分
节点流: 具有实际传输数据的读写功能.
过滤流: 在街电流的基础之上增强功能.
(详细解释:
节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。
FileInputStream 和 FileOutputStream,节点流,用于从文件中读取或往文件中写入字节流。如果在构造 FileOutputStream 时,文件已经存在,则覆盖这个文件。
BufferedInputStream 和 BufferedOutputStream,过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。
DataInputStream 和 DataOutputStream,过滤流,需要使用已经存在的节点流来构造,提供了读写 Java 中的基本数据类型的功能。)
3、IO 流的作用
用来处理设备间数据传输问题
常见的应用:文件复制、文件上传、文件下载
4、IO 流的使用场景
? ? ?如果操作的是纯文本文件,优先使用字符流
? ? ?如果操作的是二进制文件,优先使用字节流
? ? ?如果不确定,则优先使用字节流
二、字节流
=========
1、字节流抽象基类
InputStream:字节输入流的所有类的超类
OutputStream:字节输出流的所有类的超类
子类名特点:子类名称都是以其父类名作为子类名的后缀
2、字节流写数据
(1)基本步骤
? ? ? 创建 FileOutputStream 对象,关联到一个文件路径
? ? ? 调用 write()方法,写出数据
? ? ? 调用 close()方法,释放资源
? ? ? 打开文件,查看内容
(2)三种方式
? ? ? write(int b)?? ??? ? ? ? ? ?一次写一个字节数据
? ? ? write(byte[] arr)?? ??? ? ? ? ? ? 一次写一个字节数组
? ? ? write(byte[] arr,int index,int len) ? ? 写字节数组的一部分
(3)两个问题
如何写换行
调用 write()方法,写出”\r\n”.getBytes()即可
如何文件续写
? ? ?使用 FileOutputStream(String name,boolean append)构造方法
? ? ?构造方法中第二个参数传递 true,则在文件末尾继续写数据?
?(4)异常处理
字节流写数据同时处理异常的重要步骤
? ? ?将创建字节流对象和写出数据的代码放在 try 中
? ? ?在 catch 中捕获 IOException 异常
? ? ?在 finally 中进行释放资源
3、字节缓冲流
(1)基本分类 &概述
BufferedOutputStream
类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
BufferedInputStream
创建 BufferedInputStream 将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
?(2)构造方法
| BufferedOutputStream(OutputStream out) | 创建字节缓冲输出流对象 |
| BufferedInputStream(InputStream in) ? ?| 创建字节缓冲输入流对象 |
(3)代码演示?
public class BufferStreamDemo {
public static void main(String[] args) throws IOException {
//字节缓冲输出流:BufferedOutputStream(OutputStream out)
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\bos.txt"));
//写数据
bos.write("hello\r\n".getBytes());
bos.write("world\r\n".getBytes());
//释放资源
bos.close();
//字节缓冲输入流:BufferedInputStream(InputStream in)
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\bos.txt"));
//一次读取一个字节数据
// int by;
// while ((by=bis.read())!=-1) {
// System.out.print((char)by);
// }
//一次读取一个字节数组数据
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1) {
System.out.print(new String(bys,0,len));
}
//释放资源
bis.close();
}
}
三、字符流
=========
1、概念
由于字节流操作中文不是特别的方便,所以 Java 就提供字符流
字符流 = 字节流 + 编码表
(补充):中文的字节存储方式
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数?
2、分类
(1)字符流体系图
(2)字符输入流(Reader)
(3)字符输出流(Writer)
3、字符缓冲流
(1)概念
BufferedWriter
将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途。
BufferedReader
从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。?
(2)构造方法?
| BufferedWriter(Writer out) | 创建字符缓冲输出流对象 |
| BufferedReader(Reader in) ?| 创建字符缓冲输入流对象 |
(3)代码演示
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
//BufferedWriter(Writer out)
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\bw.txt"));
bw.write("hello\r\n");
bw.write("world\r\n");
bw.close();
//BufferedReader(Reader in)
BufferedReader br = new BufferedReader(new FileReader("myCharStream\bw.txt"));
//一次读取一个字符数据
// int ch;
// while ((ch=br.read())!=-1) {
// System.out.print((char)ch);
// }
//一次读取一个字符数组数据
char[] chs = new char[1024];
int len;
while ((len=br.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
br.close();
}
}
(4)字符缓冲流特有功能
void newLine()写一行行分隔符,行分隔符字符串由系统属性定义
String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为 null
四、IO 特殊操作流
=============
1、标准输入输出流
public static final InputStream in:标准输入流。
通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源。
使用步骤:
1.我们可以自己实现键盘录入输入。
BufferedReader(InputStreamReader(System.in));
调用 readtLine()方法接收数据。
2.但是上面的方式太麻烦了,所以我们直接使用键盘输入的类
Scanner sc = new Scanner(System.in);
public static final PrintStream out:标准输出流。
通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标。
使用步骤:
输出语句本质就是一个标准输出流
创建标准输出流对象:PrintStream ps = System.out;
调用 print()方法可以输出不带换行效果的数据
调用 println()方法可以输出带换行效果的数据
2、打印流
字节打印流:PrintStream
- PrintStream(String fileName):使用指定的文件名创建新的打印流。
- 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出。
- 可以改变输出语句的目的地。
字符打印流:PrintWriter
PrintWriter(String ? fileName):使用指定的文件名创建一个新的 PrintWriter,而不需要自动执行刷新。
PrintWriter(Writer ? out, boolean autoFlush):
创建一个新的 PrintWriter ? ?out:字符输出流。? ?
autoFlush: 一个布尔值,如果为真,则 println , printf ,或 format 方法将刷新输出缓冲区。?
3、对象序列化流
对象序列化流(?ObjectOutputStream):
将 Java 对象的原始数据类型和图形写入 OutputStream。 可以使用 ObjectInputStream 读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象 。
构造方法:
ObjectOutputStream(OutputStream out)
创建一个写入指定的 OutputStream 的 ObjectOutputStream。
序列化对象的方法:
void writeObject(Object obj)
将指定的对象写入 ObjectOutputStream。
4、对象反序列化流
对象反序列化流(ObjectInputStream):
反序列化先前使用 ObjectOutputStream 编写的原始数据和对象。
构造方法:
ObjectInputStream(InputStream in)
创建从指定的 InputStream 读取的 ObjectInputStream
反序列化对象的方法:
Object readObject()
从 ObjectInputStream 读取一个对象
五、补充知识
======
1、集合(Properties 集合)
(1)概念:
- 是一个 Map 体系的集合类
- Properties 可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
(2)Properties 作为 Map 集合的特有方法
《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】
1、Object ? setProperty(String key, String value)
设置集合的键和值,都是 String 类型,底层调用 ? Hashtable 方法 put
2、String ? getProperty(String key)
使用此属性列表中指定的键搜索属性
3、Set<String> ? stringPropertyNames()
从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
?(3)Properties 和 IO 流相结合的方法
1、void ? load(InputStream inStream)
?? ?从输入字节流读取属性列表(键和元素对)
2、void ? load(Reader reader)
?? ?从输入字符流读取属性列表(键和元素对)
3、void ? store(OutputStream out, String comments)
?? ?将此属性列表(键和元素对)写入此 ? Properties 表中,以适合于使用 ? load(InputStream)方法的格式写入输出字节流
4、void ? store(Writer writer, String comments)
?? ?将此属性列表(键和元素对)写入此 ? Properties 表中,以适合使用 ? load(Reader)方法的格式写入输出字符流
?(4)、示例代码
public class PropertiesDemo03 {
public static void main(String[] args) throws IOException {
//把集合中的数据保存到文件
// myStore();
//把文件中的数据加载到集合
myLoad();
}
private static void myLoad() throws IOException {
Properties prop = new Properties();
//void load(Reader reader):
FileReader fr = new FileReader("myOtherStream\fw.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}
private static void myStore() throws IOException {
Properties prop = new Properties();
评论