IO流详解
文章目录
一、File类的使用
File类的理解:
1、File类的一个对象,代表一个文件或一个文件目录
2、File类声明在java.io包下
3、File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法, 并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成
1.1File类常用构造器
方法名称 | 说明 |
---|---|
File(String pathname) | 通过将给定的路径名,字符串转换为抽象路径名来创建新的File实例 |
File(String parent,String child) | 从父路径名,字符串和子路径名,字符串创建新的File实例 |
File(File parent,String child) | 从父抽象路径名和子路径名,字符串创建新的File实例 |
package com.nnfx.day01;
import java.io.File;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 16:24
* 创建文件
*/
public class Test02 {
public static void main(String[] args) throws IOException {
/**
* mkdir 创建文件夹
* createNewFile 创建文件的
*/
//需求:在D:\FileTest 目录中创建一个File.java
File file1 = new File("D:\\FileTest\\File.java");
//createNewFile() 如果成功创建文件 返回true 否则返回false
//当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
System.out.println(file1.createNewFile());
//需求:在D:\FileTest创建day01文件
//创建由此抽象路径名命名的目录
//判断该文件是否存在,如果存在,就创建,返回true,创建失败则返回false
File file2 = new File("D:\\FileTest\\day01");
System.out.println(file2.mkdir());
//需求:在D:\FileTest\day02\javaweb
//创建由此抽象路径命名的目录,包括任何必需但不存在的父目录
File file3 = new File("D:\\FileTest\\day02\\javaweb");
System.out.println(file3.mkdirs());
}
}
1.2 File类创建功能
方法名称 | 作用 |
---|---|
public boolean createNewFile() | 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件 |
public boolean mkdir() | 创建由此抽象路径名命名的目录 |
public boolean mkdirs() | 创建由此抽象路径命名的目录,包括任何必需但不存在的父目录 |
package com.nnfx.day01;
import java.io.File;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 16:24
* 创建文件
*/
public class Test02 {
public static void main(String[] args) throws IOException {
/**
* mkdir 创建文件夹
* createNewFile 创建文件的
*/
//需求:在D:\FileTest 目录中创建一个File.java
File file1 = new File("D:\\FileTest\\File.java");
//createNewFile() 如果成功创建文件 返回true 否则返回false
//当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
System.out.println(file1.createNewFile());
//需求:在D:\FileTest创建day01文件
//创建由此抽象路径名命名的目录
//判断该文件是否存在,如果存在,就创建,返回true,创建失败则返回false
File file2 = new File("D:\\FileTest\\day01");
System.out.println(file2.mkdir());
//需求:在D:\FileTest\day02\javaweb
//创建由此抽象路径命名的目录,包括任何必需但不存在的父目录
File file3 = new File("D:\\FileTest\\day02\\javaweb");
System.out.println(file3.mkdirs());
}
}
1.3 File类的判断方法
方法名称 | 作用 |
---|---|
boolean isDirectory() | 判断是否是文件夹 |
boolean isFile() | 判断是否是文件 |
boolean exists() | 判断文件是否存在 |
package com.nnfx.day01;
import java.io.File;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 16:43
* 判断方法
*/
public class Test03 {
public static void main(String[] args) throws IOException {
File file1 = new File("D:\\FileTest\\File.java");
//file1.isDirectory() 返回是为true 就说明它是文件夹 返回false 就不是文件夹
if (file1.isDirectory()) {
System.out.println("是文件夹");
}else {
System.out.println("不是文件夹");
}
//file1.isFile() 返回true 说明就是一个文件 返回false 就不是一个文件
if (file1.isFile()) {
System.out.println("是一个文件");
}else {
System.out.println("不是一个文件");
}
//如果该文件存在就返回true 不存在就返回false
if (file1.exists()) {
System.out.println("存在");
}else {
System.out.println("不存在");
file1.createNewFile();
System.out.println("程序自动创建该文件");
}
}
}
1.4 File类的获取方法
方法名称 | 作用 |
---|---|
String getAbsolutePath() | 获取绝对路径 |
String getPath() | 获取抽象路径名转化路径名字符串 |
String getName() | 获取文件或文件夹的名称 |
String[] list() | 获取目录下所有内容,返回字符串数组 |
File[] listFiles() | 获取目录下的所有内容,返回File对象数组 |
package com.nnfx.day01;
import java.io.File;
/**
* @author 杰仔正在努力
* @create 2022-12-06 16:53
* 获取方法
*/
public class Test04 {
public static void main(String[] args) {
File file = new File("D:\\FileTest\\");
//file.getAbsoluteFile() 获取该file类 完整路径地址 绝对路径
System.out.println(file.getAbsoluteFile());
//file.getPath()获取抽象路径名转化路径名字符串
System.out.println(file.getPath());
//如果该路径是一个文件路径,获取到的就是 文件名称.后缀 如果该路径是一个文件夹路径 获取到的就是文件夹名称
System.out.println(file.getName());
System.out.println("---------返回字符串类型----------");
String[] list = file.list();
for (String str : list) {
System.out.println(str);
}
System.out.println("---------返回文件类型----------");
File[] files = file.listFiles();
for (File f : files) {
System.out.println(f.getName());
}
}
}
1.5 File类的删除方法
方法名称· | 作用 |
---|---|
boolean delete() | 如果删除路径是一个目录,不能够直接删除目录,需要先删除该目录中所有内容,最后在删除目录。如果删除路径是一个文件可以直接删除 |
package com.nnfx.day01;
import java.io.File;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 17:20
* 删除方法
*/
public class Test06 {
public static void main(String[] args) throws IOException {
File file = new File("D:\\FileTest\\day03\\file.java");
System.out.println(file.createNewFile());
//删除文件或文件夹
//file.delete()删除文件或文件夹
/**
* 如果删除的路径是一个文件路径,则直接删除
* 如果删除的路径是一个文件夹路径,则需要先将该文件夹里面的内容删除 才可以删除该文件夹
*/
System.out.println(file.delete());
}
}
循环删除多个文件
package com.nnfx.day01;
import javax.xml.transform.Source;
import java.io.File;
/**
* @author 杰仔正在努力
* @create 2022-12-06 17:31
* 循环删除多个文件
*/
public class Test07 {
public static void main(String[] args) {
File file = new File("D:\\FileTest\\day03");
//判断该路径 如果是 文件夹路径 则删除多个文件
if (file.isDirectory()) {
System.out.println("删除路径是一个文件夹路径");
deletes(file);
}
//判断该路径 如果是文件路径
if (file.isFile()) {
System.out.println("删除路径是一个文件");
delete(file);
}
}
public static void deletes(File file) {
//1、获取到该目录中的所有文件
File[] files = file.listFiles();
for (File f : files) {
f.delete();
System.out.println("删除文件:" + f.getAbsolutePath());
}
//2、删除目录
file.delete();
System.out.println("删除目录:" + file.getAbsolutePath());
}
public static void delete(File file) {
file.delete();
System.out.println("删除文件" + file.getAbsolutePath());
}
}
1.6 绝对路径和相对路径
绝对路径:物理硬盘真实存的路径
相对路径:相对路径是java工程中要访问的文件相对于当前文件的位置
package com.nnfx.day01;
import java.io.File;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 17:04
* 绝对路径 相对路径
*/
public class Test05 {
public static void main(String[] args) throws IOException {
File file = new File("file.java");
//底层自动填充绝对路径 获取当前项目路径
//D:\IOFile\file.java
System.out.println(file.createNewFile());
//获取绝对路径
System.out.println(file.getAbsolutePath());
System.out.println(file.getPath());
/**
* 绝对路径是写死的 如果将代码放入到其他电脑上运行 如果该电脑没有这个路径 就会报错
* 相对路径:动态获取运行项目路径--灵活
*
*/
}
}
二、IO流原理及流的分类
1、 I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输
2、Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行
3、java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据
原理示意图
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
.根据数据流向分类
数据流向 | 作用 |
---|---|
输入流 | 读数据 将硬盘中的数据读取到内存中 |
输出流 | 写数据 将程序中的数据写入到硬盘中 |
按照数据类型来分
数据类型 | 作用 |
---|---|
字节流 | 字节输入流/字节输出流 |
字符流 | 字符输入流/字符输出流 |
说明:
1、纯文本文件,优先使用字符流
2、图片、视频、音频等二进制文件,优先使用字节流
3、在我们不确定内容是什么,优先使用字节流
三、字节流
3.1 字节流写入数据
抽象类 | 说明 |
---|---|
InputStream | 字节输入流的所有类的超类 |
OutputStream | 字节输出流的所有类的超类子类名 |
FileOutputStream | 文件输出流用于将数据写入File |
.FileOutputStream(Stringname) | 创建文件输出流以指定的名称写入文件 |
字节流写入数据常用的三种方式
方法名称 | 说明 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流 一次写一个字节数据 |
void write(byte[] b) | 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) | 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据 |
说明:程序中出现的异常需要使用try-catch-finally处理。
package com.nnfx.day01;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 23:17
* 正确关闭IO流
*/
public class Test14 {
public static void main(String[] args) {
FileOutputStream f = null;
try {
f = new FileOutputStream("file.txt");
f.write("abcde".getBytes());
int j = 1 / 0;
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭资源
if (f!=null) {
try {
f.close();
System.out.println("关闭IO资源成功!!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
方法一:
package com.nnfx.day01;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 22:02
* 字节输出流
*/
public class Test11 {
/**
* 将程序中的数据写入到磁盘中
* @param args
*/
public static void main(String[] args) throws IOException {
//指定写入文件的路径 需要抛出异常
/**
* 1、调用系统功能创建文件 mybatis.txt
* 2、创建字节输出流对象
* 3、字节输出流对象指向文件
*/
FileOutputStream fileOutputStream = new FileOutputStream("D:\\FileTest\\day02\\mybatis.txt");
//写入数据到磁盘中
fileOutputStream.write(98);
//关闭字节输出类
fileOutputStream.close();
}
}
方法二:
package com.nnfx.day01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 22:29
* 字节流写入数据的三种方式
*/
public class Test12 {
/**
* 使用输出流写入数据的三种方式
* @param args
*/
public static void main(String[] args) throws IOException {
/**
* 创建FileOutputStream
* 直接调用到FileOutputStream("路径") 底层就是 new File("file.txt")
* byte[] bytes = {97, 98, 99, 100}; 直接写入字节数组的数据到磁盘当中 效率非常高
*/
FileOutputStream fileOutputStream = new FileOutputStream(new File("file.txt"));
byte[] bytes = {97, 98, 99, 100};
fileOutputStream.write(bytes);
//关闭资源
fileOutputStream.close();
}
}
方法三:
package com.nnfx.day01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 22:29
* 字节流写入数据的三种方式
*/
public class Test12 {
/**
* 使用输出流写入数据的三种方式
* @param args
*/
public static void main(String[] args) throws IOException {
/**
* 创建FileOutputStream
* 直接调用到FileOutputStream("路径") 底层就是 new File("file.txt")
* byte[] bytes = {97, 98, 99, 100}; 直接写入字节数组的数据到磁盘当中 效率非常高
*/
FileOutputStream fileOutputStream = new FileOutputStream(new File("file.txt"));
byte[] bytes = {97, 98, 99, 100};
fileOutputStream.write(bytes,1,bytes.length-1);//98 99 100
//关闭资源
fileOutputStream.close();
}
}
3.2 字节流写入数据换行和追加写
1、定义文件路径时,注意:可以用“/”或者“\”
2、在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖
3、如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容
package com.nnfx.day01;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 22:45
* 字节流写入数据换行和追加写
*/
public class Test13 {
public static void main(String[] args) throws IOException {
/**
* 第二个参数如果是为true,则表示追加写入数据
*/
FileOutputStream f = new FileOutputStream("file.txt",true);
for (int i = 0;i < 10;i++) {
f.write("12345".getBytes());
//换行
f.write("\n".getBytes());
}
f.close();
}
}
3.3 字节流读取数据
读取磁盘中我们想要的文本内容,并且在控制台输出,我们可以通过FileInputStream读取磁盘文件中的数据
抽象类 | 说明 |
---|---|
FileInputStream | 从文件系统中的文件获取输入字节 |
FileInputStream(String name) | 通过打开与实际文件的连接来创建一个FileInputStream,该文件有文件系统中的路径名name命名 |
步骤:
1、创建字节输入流对象
2、调用字节输入流对象的读数据方法
3、释放资源
字节流读取数据
方法名称 | 说明 |
---|---|
int read() | 从该输入流读取一个字节数据,返回值为-1时说明文件读取完毕 |
说明点: 1、 read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
2、异常的处理:为了保证流资源一定可以执行关闭操作。要使用try-catch-finally处理 3、
读入的文件一定要存在,否则就FileNotFoundException
package com.nnfx.day01;
import javax.security.auth.callback.CallbackHandler;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-06 23:31
* FileInputStream单个字节读取文件
*
*/
public class Test15 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
// //1、创建FileInputStream 输入流 读取磁盘中的数据到内存中
fileInputStream = new FileInputStream("D:\\IOFile\\spring.txt");
System.out.println("读取到的文件内容:");
int read;
/**
*1、 read = fileInputStream.read() 表示赋值操作
*2、 read != -1
*/
while ((read = fileInputStream.read()) != -1) {
System.out.print((char) read);
}
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}finally {
//3、释放资源
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.4 字节流复制数据
当我们需要把某一个文件目录下的文本拷贝到另一个文件的目录下,这时就可以使用到字节流复制数据进行操作
package com.nnfx.day01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-07 14:23
* 字节流文件内容拷贝
*/
public class Test16 {
public static void main(String[] args) throws IOException {
//1、需要读取到磁盘中的 D:\IOFile\java1\java.txt 文件到内存中
FileInputStream input = new FileInputStream("D:\\IOFile\\java1\\java.txt");
//2、需要将该内容写入到 D:\IOFile\java2\java.txt
FileOutputStream output = new FileOutputStream("D:\\IOFile\\java2\\java.txt");
int by;
while ((by=input.read())!=-1) {
output.write(by);
}
//3、释放资源
input.close();
output.close();
}
}
3.5 字节流读取字节数组数据
package com.nnfx.day01;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-07 20:18
* 字节流读取字节数组数据
*/
public class Test18 {
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("D:\\IOFile\\spring.txt");
byte[] bytes = new byte[1024]; //整数倍数
int len;
/**
* 读取到数据 字节数组长度 >0
* 如果没有读取到数据 -1
* 循环形式读取数据 每次以1024字节读取数据
* 如果能够读取到数据 len>0 true
* 将该数据转化为string类型
* 如果能够读取不到数据 len-1 false
* != -1 读取不到数据
*/
while ((len = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes,0,len));
}
inputStream.close();
}
}
3.6 字节流复制图片
当我们需要把某一个文件目录下的图片拷贝到另一个文件的目录下,这时就可以使用到字节流复制图片进行操作
package com.nnfx.day01;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-07 20:35
* 字节流复制图片
*/
public class Test19 {
public static void main(String[] args) throws IOException {
//1、程序需要读取将D:\IOFile\java1\pic.jpg 到程序中
FileInputStream fileInputStream= new FileInputStream("D:\\IOFile\\java1\\pic.jpg");
byte[] bytes = new byte[1024];
int len;
//2、再将该图片写入到D:\IOFile\java2\目录
FileOutputStream fileOutputStream = new FileOutputStream("D:\\IOFile\\java2\\pic.jpg");
while ((len=fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,len);
}
//3、关闭资源
fileInputStream.close();
fileOutputStream.close();
}
}
四、字符流
字符流:就是在字节流的基础上,加上编码,形成的数据流
字符流底层还是用的字节流,字符流仅仅做字符和字节的转换!接收一个字节流,生成的一个字符流。把字节流转换为字符流。底层会用字节流去硬盘读取字节数据,把字节数据转换为字符数据,然后返回。实现了把字节数据转换为字符数据
4.1 字符流写入数据
方法名称 | 作用 |
---|---|
public void write(int c) | 写出一个字符 |
public void write(char[] cbuf) | 写出字符数组 |
public void write(char[] cbuf,int off,int len) | 写出字符数组cbuf中,从off开始,共len个字符 |
public void write(String str) | 写出字符串 |
public void write(String str,int off,int len) | 写出字符串,从off开始,共len个字符 |
package com.nnfx.day01;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* @author 杰仔正在努力
* @create 2022-12-08 14:24
* 字符流写入数据
*/
public class Test24 {
public static void main(String[] args) throws IOException {
//1、在D:\IOFile\spring.txt 文本内容写入 中华人民共和国万岁 中国共产党万岁 中国人民万岁
//字符流:对字节流包装
//创建输出写入字符流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\spring.txt"));
outputStreamWriter.write("中华人民共和国万岁\n中国共产党万岁\n中国人民万岁");
outputStreamWriter.close(); //关闭资源
}
}
package com.nnfx.day01;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* @author 杰仔正在努力
* @create 2022-12-08 14:42
* public void write(char[] cbuf)
*/
public class Test26 {
public static void main(String[] args) throws IOException {
//创建一个字符输出流对字节输出流做包装
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\springboot.txt"));
//写出字符数组cbuf中,从off开始,共len个字符
//参数1 char类型数组
//参数2 从什么位置开始写入数据 index=3
//参数3 需要写入几个字符
char[] chars = {'a','b','c','中','国'};
outputStreamWriter.write(charss,3,2);
outputStreamWriter.close();
}
}
package com.nnfx.day01;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* @author 杰仔正在努力
* @create 2022-12-08 14:42
* public void write(String str,int off,int len)
*/
public class Test26 {
public static void main(String[] args) throws IOException {
//创建一个字符输出流对字节输出流做包装
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\springboot.txt"));
//写出字符串,从off开始,共len个字符
outputStreamWriter.write("中华人民共和国万岁",0,7);
outputStreamWriter.close();
}
}
4.2 字符流读取数据
方法名称 | 作用 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
package com.nnfx.day01;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author 杰仔正在努力
* @create 2022-12-08 15:01
* 字符流读取数据
*/
public class Test27 {
public static void main(String[] args) throws IOException {
//1、创建字节输入流(字符输入流 底层基于字节输入流)
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\IOFile\\springboot.txt"));
//读取单个字符
int read1 = inputStreamReader.read();
System.out.println((char)read1);
inputStreamReader.close();
}
}
package com.nnfx.day01;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author 杰仔正在努力
* @create 2022-12-08 15:01
* 字符流读取数据
*/
public class Test27 {
public static void main(String[] args) throws IOException {
//1、创建字节输入流(字符输入流 底层基于字节输入流)
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\IOFile\\springboot.txt"));
//一次读一个字符数组数据
char[] chars = new char[1024];
//单次以1024个字符数组读取数据 返回值 就是实际读取到长度
int len = inputStreamReader.read(chars);
System.out.println("实际读取到的长度:" + len);
System.out.println(new String(chars,0,len));
inputStreamReader.close();
}
}
4.3 字符流拷贝文本文件
package com.nnfx.day01;
import java.io.*;
/**
* @author 杰仔正在努力
* @create 2022-12-08 15:21
* 字符流拷贝文本文件
*/
public class Test28 {
public static void main(String[] args) throws IOException {
//1、使用字符流 读取到 D:\IOFile\java1\java.txt 到程序中
//字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\IOFile\\java1\\java.txt"));
//字符输出流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\java2\\java.txt"));
char[] chars = new char[1024];
int len;
while ((len = inputStreamReader.read(chars)) != -1) {
//2、将读取到文本文件内容写入到D:\IOFile\java2\ 目录下
outputStreamWriter.write(chars,0,len);
}
inputStreamReader.close();
outputStreamWriter.close();
}
}
五、缓冲流
1、当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
2、当使用BufferedInputStream读取字节文件时BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组
3、向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流
4、关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流
5、如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出
作用:
提供流的读取、写入的速度
5.1 字节缓冲流
数据类型 | 说明 |
---|---|
BufferedInputStream | 字节缓冲输入流 |
BufferedOutputStream | 字节缓冲输出流 |
package com.nnfx.day01;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-07 21:05
* 字节缓存输入流
*/
public class Test21 {
public static void main(String[] args) throws IOException {
//1、创建了一个字节输入流对象 指定读取磁盘文件路径
FileInputStream fileInputStream = new FileInputStream("D:\\IOFile\\java1\\springboot.txt");
//2、创建了一个BufferedInputStream 指定 fileInputStream
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//3、申请以块的形式读取数据
int len;
byte[] bytes = new byte[1024];
while ((len = bufferedInputStream.read(bytes)) != -1) {
//len 实际读取到的数据
System.out.println(new String(bytes,0,len));
}
bufferedInputStream.close();
}
}
package com.nnfx.day01;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-07 20:51
* 字节缓存输出流
*/
public class Test20 {
public static void main(String[] args) throws IOException {
//输出流 写入数据到磁盘中
//1、创建一个字节输出流对象 填写写入数据 磁盘路径
FileOutputStream fileOutputStream = new FileOutputStream("D:\\IOFile\\java1\\springboot.txt");
//2、创建的字节缓存区输出流 在构造方法中传递的 字节输出流对象---- 因为字节缓冲流输出流本质对字节流封装以块的形式写入数据
//字节缓冲流 缓冲区的默认大小为8192字节 8KB
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bufferedOutputStream.write("abcdefg\nhijklmn".getBytes());
bufferedOutputStream.close();
}
}
5.2 字节缓冲流复制视频
package com.nnfx.day01;
import javafx.util.converter.ByteStringConverter;
import java.io.*;
/**
* @author 杰仔正在努力
* @create 2022-12-07 21:12
* 字节缓冲区复制视频
*/
public class Test22 {
public static void main(String[] args) throws IOException {
//原理:
/**
* 1、程序需要读取到磁盘中:D:\IOFile\java1\video.mp4 到内存中
* 2、将视频写入到D:\IOFile\java2\目录
*/
//创建字节输入缓冲流
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:\\IOFile\\java1\\video.mp4"));
//创建字节输出缓冲流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\IOFile\\java2\\video.mp4"));
int len;
byte[] bytes = new byte[1024];
while ((len=bufferedInputStream.read()) != -1) {
//输出到D:\IOFile\java2\
bufferedOutputStream.write(bytes);
}
//关闭资源
bufferedInputStream.close();
bufferedOutputStream.close();
}
}
5.3 字符缓冲流
数据类型 | 说明 |
---|---|
BufferedWriter | 字符缓冲写入流 |
BufferedReader | 字符缓冲输入流 |
1、BufferedReader:从字符输入流读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
2、将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
package com.nnfx.day01;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-08 16:20
* 字符缓冲流写入数据换行操作
*/
public class Test31 {
public static void main(String[] args) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\IOFile\\a.txt"));
for (int i = 1;i<=10; i++) {
bufferedWriter.write("lisi:" + i);
bufferedWriter.newLine();
}
bufferedWriter.close();
}
}
package com.nnfx.day01;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-08 16:21
* 字符缓冲流读取数据换行操作
*/
public class Test32 {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\IOFile\\a.txt"));
String s;
while ((s = bufferedReader.readLine()) != null) {
System.out.println(s);
}
bufferedReader.close();
}
}
5.4 字符缓冲流复制文本文件
package com.nnfx.day01;
import java.io.*;
/**
* @author 杰仔正在努力
* @create 2022-12-08 16:22
* 字符缓冲流拷贝
*/
public class Test33 {
public static void main(String[] args) throws IOException {
//1、需要将硬盘中的Test01.java 读取到程序中
BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\IOFile\\java1\\Test01.java"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\IOFile\\java2\\Test01.java"));
//2、一行一行读取数据
String s;
while ((s = bufferedReader.readLine()) != null) {
bufferedWriter.write(s);
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.close();
}
}
5.5 编码和解码
编码表的由来:
计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表
编码 | 说明 |
---|---|
ASCII | 美国标准信息交换码, 用一个字节的7位可以表示 |
ISO8859-1 | 拉丁码表。欧洲码表用一个字节的8位表示 |
GB2312 | 中国的中文编码表。最多两个字节编码所有字符 |
GBK | 中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码 |
Unicode | 国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示 |
UTF-8 | 变长的编码方式,可用1-4个字节来表示一个字符 |
Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体存储成什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16
编码:把我们能看懂的变成看不懂的(字符 --> 字节)
解码:把我们看不懂的变成能看懂的(字节 --> 字符)
乱码原因:编码和解码的码表不一致
package com.nnfx.day01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author 杰仔正在努力
* @create 2022-12-07 21:49
* 编码和解码
*/
public class Test23 {
public static void main(String[] args) throws IOException {
/**
* 读取磁盘中的文件乱码
* 程序中设定读取编码的格式 UTF-8
* 该文件存储在硬盘中 编码格式UTF-8
* 读取中文字符的时候 会发生乱码
*
* 字符->字节 编码 字节->字符 解码
*/
FileInputStream fileInputStream = new FileInputStream("D:\\IOFile\\nnfx.txt");
byte[] bytes = new byte[1024];
int len = fileInputStream.read(bytes);
System.out.println(new String(bytes,0,len,"GBK"));
fileInputStream.close();
}
}
六、转换流
转换流提供了在字节流和字符流之间的转换
数据流 | 说明 |
---|---|
InputStreamReader | 将字节输入流转为字符输入流,继承自Reader |
OutputStreamWriter | 将字符输出流转为字节输出流,继承自Writer |
FileWriter 类从 OutputStreamWriter 类继承而来。该类按字符向流中写入数据
ileReader类从InputStreamReader类继承而来。该类按字符读取流中数据
package com.nnfx.day01;
import java.io.*;
/**
* @author 杰仔正在努力
* @create 2022-12-08 15:30
* 转换流
* 使用FileWriter和FileReader 将D:\\IOFile\\java1\\java.txt 文本文件拷贝到D:\\IOFile\\java2\\目录下
*/
public class Test29 {
public static void main(String[] args) throws IOException {
// //FileWriter 写入数据
// //FileWriter 读取数据 -- 字符输入流读取数据 字符输入(编码和解码)-> 字节输入流
// //jdk进行二次封装 对字节流封装只需要传递路径即可
FileReader fileReader = new FileReader("D:\\IOFile\\java1\\java.txt");
FileWriter fileWriter = new FileWriter("D:\\IOFile\\java2\\java.txt");
int len;
char[] chars = new char[1024];
while ((len = fileReader.read(chars)) != -1) {
fileWriter.write(chars,0,len);
}
fileReader.close();
fileWriter.close();
//总结:FileReader和 FileWriter 就是对当前字符流对象做了二次封装 不需要传递字节流对象了
}
}