IO 流的继承体系结构
第一章 File文件类
1.1 File类介绍
java.io.File类
- 该类的每一个实例用于表示硬盘上的一个文件或目录
- 文件系统:是操作系统中有一个子系统称为,文件系统是用来管理硬盘的,它将数据保存在文件中,并使用目录来归类,、、
- File类就是用来访问文件系统中的文件和目录的
1.2 File的主要功能
File可以:
- 1、访问其表示的文件或目录的属性信息,比如:名字,大小,修改时间等
- 2、可以创建或删除文件和目录
- 3、可以访问目录中的一个子项
- 4、但是不能访问文件数据(java中有其他API可以做这个事情)
1.3 入门案例
/**
* File类
*/
public class FileDemo001 {
public static void main(String[] args) {
/*
1.访问当前项目下的001test.txt文件,
参数可以是绝对路径,也可以是相对路径
一般使用相对路径
* */
File file = new File("./001test.txt");
//获取文件名称
String name = file.getName();
//获取文件大小,单位是字节,表示单个文件的字节量
long length = file.length();
System.out.println("文件名称是:"+name);
System.out.println("文件字节量是"+length+"个字节");
//文件是否是可读,是否是可写, 是否隐藏
boolean canRead = file.canRead();
boolean canWrite = file.canWrite();
boolean hidden = file.isHidden();
System.out.println("可读"+canRead);
System.out.println("可写"+canWrite);
System.out.println("是否隐藏"+hidden);
//获取文件的绝对路径
String absolutePath = file.getAbsolutePath();
System.out.println(absolutePath);
}
}
1.4 File 创建文件案例
/**
* 使用File创建一个文件
*/
public class FileDemo002 {
public static void main(String[] args) throws IOException {
//在当前目录下创建文件002demo.txt
File file = new File("./002demo.txt");
/*
boolean exisit()
判断当前File表示的文件目录是否已经存在
*/
if (file.exists()){
System.out.println("改文件已经存在");
}else {
file.createNewFile();
System.out.println("改文件创建成功");
}
}
}
- 第一次运行
- 再次运行
1.5 File 删除一个文件
1、创建文件
- 在项目根目录下创建003demo.txt文件
2、编写代码
/**
* 删除一个文件
*/
public class FileDemo003 {
public static void main(String[] args) {
//将当前目录下的003demo.txt文件删除
//相对路径中的“./”可以忽略不写,默认就是从“./”开始的
//File file = new File("./003demo.txt");
File file = new File("003demo.txt");
if (file.exists()){
//删除文件
file.delete();
System.out.println("文件删除成功");
}else {
System.out.println("文件不存在");
}
}
}
3、运行查看结果
1.6 File 批量创建文件
- 在当前目录下创建10个文件,分别命名为 004test1.txt 004test2.txt ----- 004test10.txt
/**
* 在当前目录下创建10个文件
* 分别命名为 004test1.txt 004test2.txt ----- 004test10.txt
*/
public class FileDemo004 {
public static void main(String[] args) throws IOException {
for (int i=1;i<=10;i++){
//创建文件
File file = new File("004test"+i+".txt");
//判断文件是否存在
if (!file.exists()){
//创建文件
file.createNewFile();
System.out.println("文件创建成功");
}
}
}
}
- 运行查看结果
1.7 File 创建单级目录
- 代码编写
/**
* File 创建目录
*/
public class FileDemo005 {
public static void main(String[] args) {
//在当前项目目录下创建一个新的目录005dir
File dir = new File("./005dir");
//判断文件夹是否存在
if (dir.exists()){
System.out.println("该目录已经存在");
}else {
//创建文件夹
dir.mkdir();
System.out.println("该目录创建成功");
}
}
}
- 运行查看结果
1.8 File 创建多级目录
- 代码编写
/**
* File 创建目录
*/
public class FileDemo006 {
public static void main(String[] args) {
//在当前项目目录下创建一个新的目录006dirs/a/b/c/d/e/f
File dir = new File("./006dirs/a/b/c/d/e/f");
//判断文件夹是否存在
if (dir.exists()){
System.out.println("该目录已经存在");
}else {
//创建文件夹
dir.mkdirs();
System.out.println("该目录创建成功");
}
}
}
- 运行查看结果
1.9 File 删除项目目录下指定目录
-
在当前项目下创建007dir目录
-
编写代码
/**
* File 删除目录
*/
public class FileDemo007 {
public static void main(String[] args) {
//将当前项目目录下的007dir删除
File dir = new File("./007dir");
//判断吗目录是否存在
if (dir.exists()){
//删除目录操作
dir.delete();
System.out.println("目录删除成功");
}else {
System.out.println("目录不存在");
}
}
}
- 运行查看结果
- 注意事项:
使用delete方法删除目录时,
要求该目录必须是一个空目录,才可以将其删除
1.10 File 获取目录中的所有子项
-
获取当前目录中的所有子项,其中 ”.“ 就表示当前目录
-
编写代码
/**
* File 获取一个目录中的所有子项
*/
public class FileDemo008 {
public static void main(String[] args) {
//获取当前目录中的所有子项,其中 ”.“ 就表示当前目录
/*
//用来判断当前File是否是一个文件
boolean isFile()
//用来判断当前File是否是一个文件夹
boolean isDirtory()
*/
File dir = new File(".");
//判断是否是一个文件夹
if (dir.isDirectory()){
//获取当前目录下的所有文件目录
/*
File[] listFiles
将当前File表示的目录中所有子项返回
每个子项(文件或目录)都以一个File对象形式存入数组
并最终将数组返回
*/
File[] listFiles = dir.listFiles();
//输出文件数组长度
System.out.println(listFiles.length);
//遍历文件数组
for (int i=0;i<listFiles.length;i++){
//获取文件数组中每个元素的名称
System.out.println(listFiles[i].getName());
}
}
}
}
- 运行获取结果
1.1 FileFilter 过滤文件获取指定后缀名的文件
- 过滤所有文件获取当前目录下的所有文本文件(.txt文件)
- 编写代码
/**
* File 重载的ListFiles方法
* File [] listFiles(FileFilter filter)
* 该方法需要我们传入一个文件过滤器,然后将该目录中满足这个过滤器要求的的子项返回
*/
public class FileDemo009 {
public static void main(String[] args) {
//获取当前目录下的所有文本文件(.txt文件)
File dir = new File(".");
//判断是否是一个文件夹
if (dir.isDirectory()) {
//创建过滤器对象
MyFilter myFilter = new MyFilter();
//获取当前目录下的所有文件目录,并进行过滤操作
File[] listFiles = dir.listFiles(myFilter);
//输出文件数组长度
System.out.println(listFiles.length);
//遍历文件数组
for (int i = 0; i < listFiles.length; i++) {
//获取文件数组中每个元素的名称
System.out.println(listFiles[i].getName());
}
}
}
}
class MyFilter implements FileFilter{
@Override
public boolean accept(File file) {//所有的子项进行过滤
//获取子项的名称
String name = file.getName();
System.out.println("正在过滤的文件名称是"+name);
//获取以为.txt接吻的文件名称
return name.endsWith(".txt");
}
}
- 运行查看结果
第二章 文件流
文件流属于节点流,是低级流
2.1 IO字节流简介
Java IO 输入与输出
IO是用来完成我们的程序与外界交换数据的方式
将输入和输出按照方向分为读与写的操作
其中,以程序为参照物
输入负责读取read,是外界到程序的方向
输出负责写出write。是程序向外界的方向
Java中定义的输入流和输出流,可以看做是连接程序与外界设备的“管道”
管道中,存在着向着同一个方向顺序移动的字节数据
实际开发中,读写不同的设备会使用专门的输入流与输出流
如读取文件使用:文件输入流和文件输出流
Java中定义了输入流和输出流的超类,用于规范输入与输出的读写操作
java.io.InputStream是输入流的超类,所有字节输入流都继承自它
java.io.OutputStream是输出流的超类,所有字节输出流都继承自它
2.2 FOS FIS 文件字节流介绍
- 文件流:
- java.io.FileInputStream 文件输入流
- java.io.FileOutputStream 文件输出流
- 它们是用来读写文件数据的流,是连接程序与文件之间的管道
2.3 文件字节流–创建文件写入文件内容
向当前目录下的文件005fos.txt中写入文件,如果文件不存在,就会自动创建 IO_001_FileOutputStream
- 编写代码
/**
* Java IO 输入与输出
* IO是用来完成我们的程序与外界交换数据的方式
* 将输入和输出按照方向分为读与写的操作
* 其中,以程序为参照物
* 输入负责读取read,是外界到程序的方向
* 输出负责写出write。是程序向外界的方向
*
* Java中定义的输入流和输出流,可以看做是连接程序与外界设备的“管道”
* 管道中,存在着向着同一个方向顺序移动的字节数据
*
* 实际开发中,读写不同的设备会使用专门的输入流与输出流
* 如读取文件使用:文件输入流和文件输出流
*
* Java中定义了输入流和输出流的超类,用于规范输入与输出的读写操作
* java.io.InputStream是输入流的超类,所有字节输入流都继承自它
* java.io.OutputStream是输出流的超类,所有字节输出流都继承自它
*
* 文件流:
* java.io.FileInputStream 文件输入流
* java.io.FileOutputStream 文件输出流
* 它们是用来读写文件数据的流,是连接程序与文件之间的管道
*
*/
public class IO_001_FileOutputStream {
public static void main(String[] args) throws IOException {
//向当前目录下的文件005fos.txt中写入文件,如果文件不存在,就会自动创建
/*
文件字节流常见的构造方法
FileOutputStream(String path)
FileOutputStream(File file) ---- > File file = new File("./005fos.dat");
*/
//创建文件输出流对象,指定文件名称、路径
FileOutputStream fos = new FileOutputStream("./005fos.dat");
/*
void write(int d)
此方法是向文件中写入1个字节,写入的内容是给定的int值对应的2进制的低八位
fos.write(1);
int型的1对应的2进制: 这八位
00000000 00000000 00000000 00000001
对应到 :005fos.dat中:
00000001
fos.write(2);
int型的1对应的2进制: 这八位
00000000 00000000 00000000 00000010
对应到 :005fos.dat中:
00000001 00000010
*/
fos.write(1);
fos.write(2);
System.out.println("写出完毕");
//关闭资源
fos.close();
}
}
- 运行查看结果
2.4 文件字节流–读取文件内容
- 编写代码
/**
* 文件输入流,用于从文件中读取字节数据到程序中
*/
public class IO_002_FileInputStream {
public static void main(String[] args) throws IOException {
//读取005fos.dat中的内容到程序中
FileInputStream fis = new FileInputStream("./005fos.dat");
/*
005fos.dat文件中存放的二进制数1,2的二进制的低八位:
00000001 00000010
*/
//读取一个字节
int read = fis.read();//第一次读取
System.out.println(read);
read = fis.read();//第二次读取
System.out.println(read);
read = fis.read();//第三次读取
System.out.println(read);
/*
int read();
从文件中读取一个字节,返回的int的值的二进制最低八位就是读取到的字节数据
如果返回的int的值为-1,则表示读取到了文件的末尾
*/
}
}
- 运行结果
2.5 文件字节流–文件复制
- 复制006.jpg文件
- 编写代码
/**
* 文件输入流,输出流进行文件赋值
*/
public class IO_003_FileInputOutputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("006.jpg");
FileOutputStream fos = new FileOutputStream("007.jpg");
//记录每次读取的字节
int d;
//判断是否读取到文件的末尾
while ((d=fis.read())!=-1){
//江都区到的字节写出去
fos.write(d);
}
System.out.println("复制成功");
fis.close();
fos.close();
}
}
- 运行查看结果
- 文件赋值原理图
2.6 文件字节流–块读写复制
- 块读写操作复制008.txt文件
- 代码编写
/**
* 高效的读写
* 通过提高每次读写的数据量,减少实际读写的次数可以提高读写效率
* 一次读写一个字节的形式是随机读写形式
* 一次读写一组字节的形式是块读写形式
*/
public class IO_004_FileInputOutputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("008.txt");
FileOutputStream fos = new FileOutputStream("008_1.txt");
/*
块读:
int read (byte[] data)
一次性读取给定的字节数组总长度的字节量并存入到该数组
返回值为实际读取到的字节量
若返回值为-1,则表示读取到了文件的末尾
块写:
void write(byte[] data)
一次性将给定的字节数组中所有的字节写出
*/
// 11110000 8位二进制---1byte也就是1字节
//创建一个长度为10kb的字节数组
byte[] data = new byte[1024*10]; //10kb
//每次读取到的字节量
int len;
//循环判断读取数据
long start = System.currentTimeMillis();
while ((len = fis.read(data))!=-1){
//将读取到的文件写出去
fos.write(data);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕,耗时"+(end-start));
fis.close();
fos.close();
}
}
- 运行结果
-
问题点:复制后的文件比原文件大,读取到了垃圾数据
-
解决方案
2.7 文件字节流–向文件中写入字符串数据
- 编写代码
/**
* 向文件中写入文本数据
* String提供了将字符串转换为一组字节的方法
* byte[] getBytes(“charsetName”)
* 按照指定的字符集将当前字符串转换为一组字节,
* 字符集的名称不区分大小写
*/
public class IO_005_FileOutputStreamTXTString {
public static void main(String[] args) throws IOException {
/*
文件默认的创建方式称为覆盖模式
即:如果指定的文件存在,则创建文件流时
会将改文件原有的数据全部抹掉,
然后将写入的数据全部保存到文件中
文件流支持一个重载的构造器,允许我们再传入一个boolean的值作为参数
如果这个值为true,
则当前文件流为追加默认
创建文件流时,若指定的文件存在,则原数据保留,
新写入的数据都会顺序追加到文件末尾
new FileOutputStream(String path, boolean append)
new FileOutputStream(File file, boolean append)
*/
FileOutputStream fos = new FileOutputStream("009fos.txt");
//将文本数据转换为二进制,写入到硬盘中 ,转码 UTF-8 GBK
String line = "我今天去输液了,输的什么液,输的是想你的夜";
/*
将字符串转换为字节,用UTF-8进行编码
*/
//方式一:标准编码常量值
//line.getBytes(StandardCharsets.UTF_8);
//方式二
byte[] bytes = line.getBytes("UTF-8");//大小写没区别
//将转换后的字节数组写出
fos.write(bytes);
System.out.println("写出完毕");
fos.close();
}
}
-
运行结果
-
文件数据的追加效果
文件默认的创建方式称为覆盖模式
即:如果指定的文件存在,则创建文件流时
会将改文件原有的数据全部抹掉,
然后将写入的数据全部保存到文件中
文件流支持一个重载的构造器,允许我们再传入一个boolean的值作为参数
如果这个值为true,
则当前文件流为追加默认
创建文件流时,若指定的文件存在,则原数据保留,
新写入的数据都会顺序追加到文件末尾
new FileOutputStream(String path, boolean append)
new FileOutputStream(File file, boolean append)
2.8 文件字节流–从文件中读取字符串数据
- 代码编写
/**
* 实现简易记事本的工具
* 程序启动后在控制台输入的每一行字符串都能顺序的写入文件010fos.txt
* 当单独输入exit时程序退出
*/
public class IO_007_TestFOS {
public static void main(String[] args) throws IOException {
//创建文件输出流,设置为追加默认
FileOutputStream fos = new FileOutputStream("010fos.txt",true);
//创建scanner对象
Scanner scanner = new Scanner(System.in);
System.out.println("请开始输入内容,单独输入exit时退出");
while (true){
//键盘输入字符串
String line = scanner.nextLine();
//判断是否要退出
if ("exit".equals(line)){
break;
}
//将字符串转换为utf-8字符集编码的字节
byte[] bytes = line.getBytes(StandardCharsets.UTF_8);
//执行块写出操作
fos.write(bytes);
}
System.out.println("再见");
//关闭资源
fos.close();
}
}
- 运行结果
2.9 图解低级流(节点流)和高级流(处理流)
-
Java IO 输入与输出
- IO是用来完成我们的程序与外界交换数据的方式
- 将输入和输出按照方向分为读与写的操作
- 其中,以程序为参照物
- 输入负责读取read,是外界到程序的方向
- 输出负责写出write。是程序向外界的方向
-
Java中定义的输入流和输出流,可以看做是连接程序与外界设备的“管道”
-
管道中,存在着向着同一个方向顺序移动的字节数据
-
实际开发中,读写不同的设备会使用专门的输入流与输出流
-
如读取文件使用:文件输入流和文件输出流
-
-
Java中定义了输入流和输出流的超类,用于规范输入与输出的读写操作
- java.io.InputStream是输入流的超类,所有字节输入流都继承自它
- java.io.OutputStream是输出流的超类,所有字节输出流都继承自它
-
文件流:
- java.io.FileInputStream 文件输入流
- java.io.FileOutputStream 文件输出流
- 它们是用来读写文件数据的流,是连接程序与文件之间的管道
-
Java将流分为两类:节点流和处理流
-
节点流:也称为低级流,是真实连接程序与另一端 ” 管道 “,负责实际读写数据的流, IO操作是基于某个节点流基础上进行的
-
处理流:也称为高级流,它不能独立存在,必须连接在其他流上,目的是当数据流经当前流时对其进行加工操作,使得我们读写数据得以简化
-
实际开发中,我们经常会串联一组高级流到某个低级流上,
-
读写数据以流水线式的加工处理,这也称为“流的链接”
-
-
文件流是一对低级流
- java.io.FileInputStream/FileOutputStream
- 他们是用来读写文件数据的流,是连接程序与文件之间的“管道"
第三章 缓冲流
缓冲流是处理流,属于高级流
3.1 缓冲流 BIS BOS
缓冲流
- java.io.BufferedInputStream和BufferedOutputStream
- 缓冲流是一对高级流,在流连接中的作用是提高读写字节数据的效率
3.2 使用缓冲流完成文件复制
-
原理图
-
代码编写
/**
* 使用缓冲流完成文件的复制
* 缓冲流
* java.io.BufferedInputStream和BufferedOutputStream
* 缓冲流是一对高级流,在流连接中的作用是提高读写字节数据的效率
*/
public class IO_plus_001_BufferedInputStream_BufferedOutputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("011.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("011_1.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int d;
long start = System.currentTimeMillis();
while ((d = bis.read())!=-1){
bos.write(d);
}
long end = System.currentTimeMillis();
System.out.println("文件复制完成需要的时间是:"+(end-start)+"ms");
bis.close();
bos.close();
}
}
- 运行结果
3.3 缓冲流的默认缓存区
BufferedInputStream和BufferedOutputStream缓冲流的默认缓存区的大小是8192字节
- 案例
/**
* 缓冲输出流的缓冲区问题
*/
public class IO_plus_002_FlushDemo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("012.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String line = "我穿了短的裙子遛弯去了";
byte[] bytes = line.getBytes(StandardCharsets.UTF_8);
bos.write(bytes);
//bos.flush(); 不关闭流,执行flush
System.out.println("写出完毕");
//关闭资源
//bos.close();
}
}
- 情况一、不关闭流执行写出操作,会发现,写出成功,但是文件中,没有内容,是因为,缓冲流的默认字节数组的大小是8192个字节,写出的内容小于默认数组的容量,数据不会自动写出,导致文件中数据不存在
- 情况二、执行输出流的 flush() 方法,将默认缓冲字节数组中的数据,写出到文件中
- 情况三、先清空文件中的内容,不执行缓冲输出流的 flush()方法,直接执行关闭流的操作,数据写出到文件成功。因为关闭流的方法中,再次调用了flush()操作。
第四章 对象流
对象流是处理流,属于高级流
4.1 对象流介绍
对象流
- 对象流是一对高级流
- 作用是:在流连接中进行对象的序列化和反序列化
- 对象序列化:是将对象按照其结构转换为一组字节
- 对象反序列化:是将一组字节还原为java对象
4.2 对象输出流–序列化对象
对象序列化:对象写入到文件中
- 原理图
- 代码
/**
* 对象流
* 对象流是一对高级流
* 作用是:在流连接中进行对象的序列化和反序列化
* 对象序列化:是将对象按照其结构转换为一组字节
* 对象反序列化:是将一组字节还原为java对象
*/
public class IO_plus_003_ObjectOutputStream {
public static void main(String[] args) throws IOException {
/*
讲一个Person对象写入文件013per.txt中
*/
//创建person对象
Person p = new Person();
p.setName("海王");
p.setAge(30);
p.setGender('女');
p.setAddr("Canada");
System.out.println(p);
//创建文件输出流
FileOutputStream fos = new FileOutputStream("013per.txt");
//创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(fos);
//执行写出才操作
/*
对象输出流提供的方法
void writeObject(Object obj)
该方法会将给定的对象按照其结构转换为一组字节,
但是要求该对象的类必须实现序列化接口,
否则会抛出异常
java.io.NotSerializableException
*/
oos.writeObject(p);
System.out.println("写出完毕");
//关闭字眼
oos.close();
}
}
- 运行查看结果
- 查看文件字节数
为什么写入的数据这么大,是因为除了讲对象本身转化为字节写入文件外,还有将对象的结构也写入到了文件中
4.3 对象输入流–反序列化对象
- 编写代码
/**
* 使用对象输入流反序列化对象
*/
public class IO_plus_004_ObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建文件输入流对象
FileInputStream fis = new FileInputStream("013per.txt");
//创建对象输入流对象
ObjectInputStream ois = new ObjectInputStream(fis);
//读取对象
Object o = ois.readObject();
//进行强制转换
Person p = (Person) o;
//输出对象
System.out.println(p);
//关闭资源
ois.close();
}
}
- 运行查看结果
第五章 转换流
转换流执行的是字符与字节转换,属于高级流
5.1 转换流介绍
Java.io 将流按照读写数据的单位划分为:字节流和字符流
-
字节流
- java.io.InputStream 和 OutputStream 是所有字节流的超类,
- 比如:文件流,缓冲流,对象流都继承自上述的两个超类,
- 读写单位最小都是以字节为单位进行的
-
字符流
- java.io.Reader 和Write 是所有字符流的超类,
- 读写单位是最小的char(字符)为单位进行的
- 字符流底层本质还是要进行字符和字节的转换(因为计算机底层只有2进制)
- 但是字符流给我们提供的便利是可以让我们直接读写文本数据
- 因此注意:字符流只适合读写文本数据!
-
转换流
- 转换流是一对高级流,实际开发中我们不直接操作这对流,
- 但是在流链接中它们是非常重要的,
- 负责衔接其他字符流与下面的字节流
- 并进行字符和字节的转换工作
- java.io.OutputStreamWriter 和 InputStreamReader
- 他们时唯一可以连接在字节流上的字符流,
- 其他字符流通过连接上它就可以与底下的字节流连接使用了
- 它们之所以被称为转换流,就相当于起到了“转换器的作用”
5.2 字符转换输出流—将字符数据写入到文本文件
- 代码编写
/**
* Java.io 将流按照读写数据的单位划分为:字节流和字符流
*
* 字字节流
* java.io.InputStream 和 OutputStream 是所有字节流的超类,
* 比如:文件流,缓冲流,对象流都继承自上述的两个超类,
* 读写单位最小都是以字节为单位进行的
*
* 字符流
* java.io.Reader 和Write 是所有字符流的超类,
* 读写单位是最小的char(字符)为单位进行的
* 字符流底层本质还是要进行字符和字节的转换(因为计算机底层只有2进制)
* 但是字符流给我们提供的便利是可以让我们直接读写文本数据
* 因此注意:字符流只适合读写文本数据!
*/
/*
* 转换流
* 转换流是一对高级流,实际开发中我们不直接操作这对流,
* 但是在流链接中它们是非常重要的,
* 负责衔接其他字符流与下面的字节流
* 并进行字符和字节的转换工作
*
* 案例:转换流,将字符转换成字节输出
*/
public class IO_plus_005_OutputStreamWrite {
public static void main(String[] args) throws IOException {
//创建字节数出流,true表示可以追加类型
FileOutputStream fos = new FileOutputStream("014osw.txt",true);
//创建字符输出流,字符输出流内部会将字符转化为字节,设置字符集编码,交给字节输出流写到指定文件中
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
//执行写出操作
osw.write("今天你打疫苗了么");
osw.write("出行需戴口罩");
//执行完毕
System.out.println("写出完毕");
//关闭资源
osw.close();
}
}
- 运行查看结果
5.3 字符转换输入流—使用转换流读取文本数据
- 代码编写
/**
* 使用转换流读取文本数据
*/
public class IO_plus_006_InputStreamReader {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("014osw.txt");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
int d ;
/*
字符流的read()方法
int read()
读取一个字符,是以int型返回的,因此该int值的二进制“低十六位”有效
如果返回的int值为-1,则表示读取到了末尾
*/
while ((d=isr.read())!=-1){
System.out.println(d);
System.out.print((char)d);
}
isr.close();
}
}
- 运行查看结果
- 原理图
第六章 缓冲字符流
6.1 缓冲字符流介绍
- 缓冲字符流
-
缓冲字符流是一对高级流
-
在流连接中的作用是提高读写文本数据的效率
-
并且可以按行读取字符串
-
java.io.BufferedReader 和 BufferedWriter
-
实际开发中缓冲字符输出流是我们常用的PrintWriter
-
具有自动行刷新功能的缓冲字符输出流
-
其内部总是连接BufferedWriter作为缓冲加速使用
-
6.2 缓冲字符流—PrintWrite 向文件中写入字符串
- 编写代码
/**
* 缓冲字符流
* 缓冲字符流是一对高级流
* 在流连接中的作用是提高读写文本数据的效率
* 并且可以按行读取字符串
* java.io.BufferedReader 和 BufferedWriter
*
* 实际开发中缓冲字符输出流是我们常用的PrintWriter
* 具有自动行刷新功能的缓冲字符输出流
* 其内部总是连接BufferedWriter作为缓冲加速使用
*/
public class IO_plus_007_BufferedReader_BufferWriter {
public static void main(String[] args) throws FileNotFoundException {
/**
* PrintWriter 提供了对文件操作的构造方法
* PrintWriter(String path)
* PrintWriter (File file)
*/
//向文件中写入字符串
PrintWriter pw = new PrintWriter("015pw.txt");
pw.println("我的梦中情人是张曼玉");
pw.println("我的梦中情人是邱淑贞");
pw.println("我的梦中情人是王祖贤");
pw.println("我的梦中情人是张敏");
System.out.println("写出完毕");
pw.close();
}
}
-
运行结果
-
流耦合原理
6.3 PrintWrite 案例
- 案例1
/**
* 在流连接中使用PW
*/
public class IO_plus_008_PWDemo {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
//低级流,文件输出流,作用:向文件中写入数据
FileOutputStream fos = new FileOutputStream("016pwtest.txt");
//高级流,转换输出流,作用:衔接其他字符流和字节流,将写出的字符转换成字节
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
//高级流,缓冲字符流,作用:块写文本数据加速
BufferedWriter bw = new BufferedWriter(osw);
//高级流,字符输出流,作用:按行写出字符串,并且可以自动行刷新
PrintWriter pw = new PrintWriter(bw);
//写出字符串
pw.write("今天要下雨");
pw.write("最近每天在下雨");
pw.write("下雨导致回不了家");
System.out.println("写出完毕");
//关闭资源
pw.close();
}
}
-
运行结果
-
案例2
/**
* 实现简易记事本工具
* 程序启动后,要求输入一个文件名,然后对改文件进行写操作
* 之后用户输入的每一行字符串都能按行写入到改文件中
* 当用户单独输入exit时,程序退出
*/
public class IO_plus_009_IODemo {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入文件名");
String fineName = sc.nextLine();
FileOutputStream fis = new FileOutputStream(fineName);
OutputStreamWriter osw = new OutputStreamWriter(fis,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
System.out.println("请开始输入内容,单独输入exit时退出");
while (true){
String line = sc.nextLine();
if ("exit".equals(line)){
break;
}
pw.println(line);
pw.flush();
}
System.out.println("再见");
pw.close();
}
}
- 运行结果