IO流相关知识点回顾
第一章节:IO流简介
概述:
I(Input,输入)/O(Output,输出)流,是Java中用来传输数据的方式。
分类:
根据流的方向分(相对于内存,输入和输出):
-
输入流:读数据
-
输出流:写数据
根据流的格式分:
-
字节流(一个字节占8位):以字节为单位来操作数据。
-
字符流:以字符为单位来操作数据。
根据流的功能分:
-
节点流:可以从某节点读数据或向某节点写数据的流
-
处理流:对已存在的流的连接和封装,实现更为丰富的流数据处理,提高流读写效率
补充:
1.ASCII码中:一个英文字符(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。 一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值0,最大值255。 1个英文字符 => 1B 1个汉字 => 2B 2.UTF-8编码中:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。 1个英文字符 => 1B 1个汉字 => 2B 3.Unicode编码中:一个英文字符等于两个字节,一个中文(含繁体)等于两个字节。符号:英文标点占一个字节;中文标点占两个字节。 1个英文字符 => 1B 1个汉字 => 2B 1个英文标点 => 1B 1个中文标点 => 2B 4.UTF-16编码中:一个英文字母字符或一个汉字字符存储都需要2个字节(Unicode扩展区的一些汉字存储需要4个字节)。 1个英文字符 => 2B 1个汉字 => 2B 5.UTF-32编码中:世界上任何字符的存储都需要4个字节。
位、字节与字符相关知识——转载至:https://blog.csdn.net/u012990687/article/details/112373316
第二章节:File类的创建及判断功能
概述:
文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹【用来处理文件(夹)路径的】。
构造方法:
-
创建功能(如果不存在就创建,返回true,否则就不创建,返回false)
File(String pathname) 根据给定的字符串路径创建其对应File对象。 File(String parent,String child) 根据给定的字符串形式的父目录和子文件(夹)名创建File对象。 File(File parent,String child) 根据给定的父目录对象和子文件(夹)名创建File对象。
-
判断功能
isDirectory() 判断File对象是否为目录 isFile() 判断File对象是否为文件 exists() 判断File对象是否存在
demo:
public static void main(String[] args) throws IOException { //需求:将D:\abc\_final.txt 封装成File对象。 //方式一:根据字符串形式的路径获取File对象。 File file1=new File("D:\\abc\\_final.txt"); System.out.println("file1:"+file1); //方式二:根据字符串形式的父目录以及子目录创建File对象。 File file2=new File("D:\\abc\\","_final.txt"); System.out.println("file2:"+file2); //方式三:根据父目录对象,以及字符串形式的子目录来获取File对象。 File file3=new File("D:\\abc\\"); File file4=new File(file3,"_final.txt"); System.out.println("file4:"+file4); //需求:在d盘下创建 2.txt文件 File file5=new File("d:/2.txt"); boolean flag1=file5.createNewFile(); System.out.println("flag1:"+flag1); //需求:在D盘下创建a文件夹 File file6=new File("D:/a"); boolean flag2=file6.mkdir(); //make directory,创建单级目录 System.out.println("flag2:"+flag2); //需求:在D盘下创建a/b/c文件夹 File file7=new File("D:/a/b/c"); boolean flag3=file7.mkdirs(); //创建多级目录(也可以创建单级目录) System.out.println("flag3:"+file3); System.out.println("----------------------"); //需求:测试判断功能 File file8=new File("D:/a/b"); System.out.println("测试file8是否是文件夹"+file8.isDirectory()); System.out.println("测试file8是否为文件"+file8.isFile()); System.out.println("测试file8是否存在"+file8.exists()); }
第三章节:File类的获取功能
getAbsolutePath(): 获取绝对路径
getPath(): 获取文件的相对路径
getName(): 获取文件名
list(): 获取指定目录下所有文件(夹)名称数组
listFiles(): 获取指定目录下所有文件(夹)File数组
demo:
public static void main(String[] args) { File file1=new File("lib/_final.txt"); //获取file1的绝对路径 String path1=file1.getAbsolutePath(); System.out.println("绝对路径:"+path1); //绝对路径:E:\IDEA\zhihui\lib\_final.txt //获取file1的相对路径 String path2=file1.getPath(); System.out.println("相对路径:"+path2); //相对路径:lib\_final.txt //获取文件名 String filename=file1.getName(); System.out.println("文件名:"+filename); //文件名:_final.txt //获取lib文件夹下所有的文件(夹)的:名称数组String[] File file2=new File("lib"); String[] names=file2.list(); for (String name : names) { System.out.print(name+" "); // _final.txt a abc } System.out.println(); //获取lib文件夹下所有的文件(夹)的:File对象数组File[] File[] files=file2.listFiles(); for (File file : files) { System.out.print(file+" "); // lib\_final.txt lib\a lib\abc } }
第四章节:字节流
FileInputStream
概念:普通的字节输入流,用来读取数据。
构造方法:
public FileInputStream(String pathname);
成员方法:
public int read(); 一次读取一个字节,并返回读取到的内容,读不到返回-1. public int read(byte[] bys); 一次读取一个字节数组,将读取到的内容存入到数组中,并返回读取到的有效字节数,读不到返回-1.
FileOutputStream
概念:普通的字节输出流,用来写数据。
构造函数
public FileOutputStream(String pathname);
成员方法
public void write(int len); 一次写入一个字节. public void write(byte[] bys,int index,int len); 一次写入一个指定的字节数组.
一次读写一个字节
demo:
public static void main(String[] args) throws IOException { FileInputStream fis=new FileInputStream("lib/a.png"); FileOutputStream fos=new FileOutputStream("lib/b.png"); int len; while((len=fis.read())!=-1){ fos.write(len); } fis.close(); fos.close(); }
读写一个字节数组
public static void main(String[] args) throws IOException { FileInputStream fis=new FileInputStream("lib/a.png"); FileOutputStream fos=new FileOutputStream("lib/b.png"); int len; byte[] bys=new byte[1024]; while((len=fis.read(bys))!=-1){ fos.write(bys,0,len); //write(byte[] b, int off, int len)方法:将指定字节数组中从偏移量off开始的len个字节写入此文件输出流 } fis.close(); fos.close(); }
第五章节:字符流读取数据
为什么会出现字符流?
答:由于字节流操作中文不是特别方便,所以Java就提供了字符流 字符流=字节流+编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文。那是如何识别中文的呢? 汉字在存储的时候,无论选择那种编码存储,第一个字节都是负数。
编码:
byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中 byte[] getBytes(String charsetName):使用自定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码:
String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来创建新的String String(byte[] bytes,String charsetName):通过指定的字符集解码到指定的字节数组来创建新的String
采用何种规则编码,就要采用对应规则解码,否则就会出现乱码
InputStreamReader&&OutputStreamWriter
InputStreamReader:是从字节流到字符流的桥梁它读取字节,并使用指定的指定编码将其解码为字符它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
OutputStreamWriter:是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码转为字节 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
InputStreamReader (InputStream in) 创建一个使用默认字符集的InputStreamReader
InputStreamReader (InputStream in, String charsetName) 创建一个使用指定charset的InputStreamReader
OutputStreamWriter (OutputStream out) 创建使用默认字符编码的OutputStreamWriter。
OutputStreamWriter (OutputStream out, String charsetName) 创建使用指定charset的OutputStreamWriter
字符流读数据(一次读取一个字符)
构造方法及成员方法
Reader类中的方法:
int read(); 读一个字符,返回该字符对应的ASCII码值,读不到返回-1。 FileReader类的构造方法: public FileReader(String pathname); 根据传入的字符串形式的路径,获取字符输入流对象。
demo
public static void main(String[] args) throws IOException { //需求:通过字符流读取数据。 //1.创建字符输入流对象。 Reader reader=new FileReader("lib/_final.txt"); //2.读取数据。 //定义变量,用来接收读取到的字符。 int ch; /* (ch=reader.read())!=-1 做了三件事 1.执行reader.read(),去文件中读取一个字符。 2.执行ch=reader.read(),将读取到的字符赋值给变量。 3.(ch=reader.read())!=-1,用读取到的字符(内容)和-1进行比较。 */ while ((ch=reader.read())!=-1){ System.out.println(ch); //97 98 99 } //3.释放资源。 reader.close(); }
字符流读取数据(读取一个字符数组)
构造方法及成员方法
字符流读取数据
Reader类中的方法: int read(char[] chs); 一次读一个字符数组,将读取到的内容存入到数组中, 并返回读取到的有效字符数,读不到返回-1。 FileReader类的构造方法: public FileReader(String pathname); 根据传入的字符串形式的路径,获取字符输入流对象。
demo
public static void main(String[] args) throws IOException { //需求:通过字符流读取数据,一次读取一个字符数组。 //1.创建字符输入对象 Reader reader=new FileReader("lib/2.txt"); //2.读取数据 //定义字符数组 char[] chs=new char[3]; //定义一个变量,记录读取到的有效字符数 int len; while ((len=reader.read(chs))!=-1){ //将读取到的内容,转换成字符串,然后打印 /* chs:表示要操作的数组。 0:表示起始索引。 len:表示要操作的字符的个数。 */ String s=new String(chs,0,len); System.out.println(s); //abc def g } //3.释放资源 reader.close(); }
第六章节:字符流写数据
构造方法及成员方法
字符流写数据的5种方式 void write(int c); 写一个字符 void write(char[] cbuf); 写入一个字符数组 void write(char[] cbuf,int off,int len); 写入字符数组的一部分 void write(String str); 写一个字符串 void write(String str,int off,int len); 写一个字符串的一部分 flush(): 刷新流,还可以继续读数据 close(): 关闭流,释放资源,但是在关闭之间会先刷新流。一旦关闭,就不能再写数据。 FileWriter类的构造方法: public FileWriter(String pathname); 根据传入的字符串形式的路径,获取字符输出流对象。
demo:
public static void main(String[] args) throws IOException { //需求:通过字符流,写数据。 //1.创建字符输出流对象。 Writer writer=new FileWriter("lib/3.txt"); //2.写数据。 // //方式一:一次写一个字符 // writer.write('好'); // //方式二:一次写一个指定的字符数组 // char[] chs={'未','来','更','好'}; // writer.write(chs,2,2); //方式三:一次写一个字符串 writer.write("知识改变命运"); //3.释放资源 writer.close(); }
第七章节:字符流拷贝数据
步骤:
-
I/O流拷贝文件核心6步:
-
创建字符输入流对象,关联数据源文件。
-
创建字符输出流对象,关联目的地文件。
-
定义变量,记录读取到的内容。
-
循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量。
-
将读取到的数据写入到 目的地文件中。
-
释放资源。注:读写文件时,如果目的地文件不存在,程序会自动创建。
一次编写一个字符
public static void main(String[] args) throws IOException { //1.创建字符输入流对象,关联数据源文件。 // Reader fr=new FileReader(); //传统写法 FileReader fr=new FileReader("lib/4.txt"); //优化写法 //2.创建字符输出流对象,关联目的地文件。 FileWriter fw=new FileWriter("lib/5.txt"); //如果目的地文件不存在,程序会自动创建 //3.定义变量,记录读取到的内容。 int len; //读一个字符,返回该字符对应的ASCII码值,读不到返回-1。 //4.循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量。 while((len= fr.read())!=-1){ //5.将读取到的数据写入到 目的地文件中。 fw.write(len); } //6.释放资源。 fr.close(); fw.close(); }
依次编写一个字符数组
public static void main(String[] args) throws IOException { //需求:通过字符流拷贝文件,一次读写一个字符数组。 //把6.txt文件中的内容复制到2.txt文件中。 //1. FileReader fr=new FileReader("lib/6.txt"); //2. FileWriter fw=new FileWriter("lib/7.txt"); //3. //定义一个字符数组 char[] chs=new char[1024]; //字符长度通常为1024的倍数 int len; //一次读一个字符数组,将读取到的内容存入到数组中, //并返回读取到的有效字符数,读不到返回-1。 //4 while ((len= fr.read(chs))!=-1){ //5 fw.write(chs,0,len); } //6 fr.close(); fw.close(); }
高效字节流用法
字节缓冲流
BufferedInputStream:BufferedInputStream将创建一个内部缓冲数组。
当从流中读取或跳过字节时,内部缓冲区将根据所包含
的输入流重新填充,一次很多字节
BufferedOutputStream:该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,
而不必为写入的每个字节导致底层系统的调用
构造方法:
字节缓冲输入流:BufferedInputStream(InputStream out)
字节缓冲输出流:BufferedOutputStream(OutputStream in)
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
答:字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
高效字节流用法
BufferedInputStream:字节缓冲输入流(也叫:高效字节输入流),用来读取数据的. 构造方法: public BufferedInputStream(InputStream is); 成员方法: public int read(); 一次读取一个字节,并返回读取到的内容,读不到返回-1. BufferedOutputStream:字节缓冲输出流(也叫:高效字节输出流),用来写数据. 构造方法: public BufferedOutputStream(OutputStream os); 成员方法: public void write(int len); 一次读取一个字节.
特点:字节缓冲流有自己的缓冲区,大小为8192个字节,也就是8kb.
demo:
public static void main(String[] args) throws IOException { BufferedInputStream bis=new BufferedInputStream(new FileInputStream("lib/a.png")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("lib/b.png")); int len; while((len= bis.read())!=-1){ bos.write(len); } bis.close(); bos.close(); }
第八章节:字符缓冲流
步骤:
-
创建字符缓冲输入流对象,关联数据源文件。
-
创建字符缓冲输出流对象,关联目的地文件。
-
定义变量,记录读取到的内容。
-
循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量。
-
将读取到的数据写入到 目的地文件中。
-
释放资源。
特点:字符缓冲流自带有缓冲区,大小为8192个字符,也就是16kb。
注意:字符流只能拷贝纯文本文件。
字符缓冲流用法
分类:
BufferedReader:字符缓冲输入流(也叫高效字符输入流)。
public static void main(String[] args) throws IOException { BufferedInputStream bis=new BufferedInputStream(new FileInputStream("lib/a.png")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("lib/b.png")); int len; while((len= bis.read())!=-1){ bos.write(len); } bis.close(); bos.close(); }
BufferedWriter:字符缓冲输出流(也叫高效字符输出流)。
构造方法: public BufferedWriter(Writer writer); 成员方法: public void newLine(); 根据当前操作系统给出对应的换行符。 window操作系统: \r\n mac操作系统: \r unix操作系统: \n
普通用法
demo:
public static void main(String[] args) throws IOException { //需求:通过字符缓冲流,将6.txt文件中的内容拷贝到7.txt文件中。 //1.创建字符缓冲输入流对象,关联数据源文件。 FileReader fr=new FileReader("lib/6.txt"); BufferedReader br=new BufferedReader(fr); //简述上述代码 //BufferedReader br=new BufferedReader(new FileReader("lib/6.txt")); //2.创建字符缓冲输出流对象,关联目的地文件。 BufferedWriter bw=new BufferedWriter(new FileWriter("lib/7.txt")); //3.定义变量,记录读取到的内容。 int len; //4.循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量。 while((len= br.read())!=-1){ //5.将读取到的数据写入到 目的地文件中。 bw.newLine(); } //6.释放资源。 br.close(); bw.close(); }
一次读写一行
步骤:
-
创建字符缓冲输入流对象,关联数据源文件。
-
创建字符缓冲输出流对象,关联目的地文件。
-
定义变量,记录读取到的内容。
-
循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量。
-
将读取到的数据写入到 目的地文件中。
-
释放资源。
demo:
public static void main(String[] args) throws IOException { BufferedReader br=new BufferedReader(new FileReader("lib/6.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("lib/7.txt")); //字符缓冲流特有方法(一般用字符缓冲流的时候都会用这种方法) String str; while((str=br.readLine())!=null){ bw.write(str); bw.newLine(); } br.close(); bw.close(); }
总结:字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能(一次读取一个字符串、一次写一个字符串)。 拷贝纯文本文件使用字符流,拷贝其它(图片,音频,视频等)使用字节流。
第九章节:打印流
打印流分类:
-
字节打印流:PrintStream
-
字符打印流:PrintWriter
打印流的特点:只负责输出数据,不负责读取数据;有自己的特有方法
PrintStream(String fileName):使用指定的文件名创建新的打印流
使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
public static void main(String[] args) throws FileNotFoundException { //PrintStream(String fileName):使用指定的文件名创建新的打印流 PrintStream ps=new PrintStream("src/_10/IO流/_10打印流/_01.txt"); //写数据 //字节输出流的方法 //使用继承父类的方法写数据,查看的时候会转码 ps.write(97); //使用自己的特有方法写数据,查看的数据原样输出 ps.println(97); ps.print(98); ps.close(); }
字符打印流
字符打印流的构造方法
PrintWriter(String fileName):使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新 PrintWriter(Writer out,boolean autoFlush):创建一个新的PrintWriter out:字符输出流 autoFlush:一个布尔值,如果为真,则println,printf,或format方法将刷新输出缓冲流
demo:
public static void main(String[] args) throws IOException { //PrintWriter(String fileName):使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新 PrintWriter pw=new PrintWriter("src/_10/IO流/_10打印流/_01.txt"); /*pw.write("hello"); pw.write("\r\n"); pw.flush(); pw.write("world"); pw.write("\r\n"); pw.flush();*/ /* pw.println("hello"); //自动换行 pw.flush(); pw.println("world"); pw.flush();*/ // PrintWriter(Writer out,boolean autoFlush):创建一个新的PrintWriter PrintWriter pw2=new PrintWriter(new FileWriter("src/_10/IO流/_10打印流/_01.txt"),true); pw2.println("hello"); pw2.println("world"); pw.close(); pw2.close(); }
复制Java文件打印流改进版
步骤
-
根据数据源创建字符输出流对象
-
根据目的地创建字符输出流对象
-
读写数据,复制文件
-
释放资源
需求:
把 src/10/IO流/10打印流/01.txt 复制到 src/10/IO流/10打印流/02.txt
public static void main(String[] args) throws IOException { BufferedReader br=new BufferedReader(new FileReader("src/_10/IO流/_10打印流/_01.txt")); PrintWriter pw=new PrintWriter(new FileWriter("src/_10/IO流/_10打印流/_02.txt"),true); String str; while((str=br.readLine())!=null){ pw.println(str); } br.close(); pw.close(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?