IO流
字节输入流
- InputStream输入流祖宗类
- FileInputStream文件输入流
public class IODemo01 {
public static void main(String[] args) {
//铺水管
try {
//方法1
FileInputStream fis = new FileInputStream("盘符:\\路径\\xxx.txt");
//方法2,更灵活
// File file = new File("盘符:\\路径\\xxx.txt");
// FileInputStream fileInputStream = new FileInputStream(file);
//开水龙头
int ch = 0;
while ((ch=fis.read())!=-1){
System.out.print((char)ch);
}
//关水龙头
fis.close();
} catch (Exception e) {
System.out.println("打开失败");
}
}
}
关于中文乱码
因为读文件是一个一个字节读的,而中文在不同的编码下,一个字符可能2个或者3个字节,因此读取一个中文字符时读的是不完整的,导致乱码
字节输出流
- OutputStream输出流祖宗类
- FileOutputStream文件输出流
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
public class IODemo02 {
public static void main(String[] args) {
try {
//数据
String data = "HelloWorld";
//铺水管
//方法一
// File file = new File("盘符:\\路径\\xxx.txt");
// FileOutputStream fileOutputStream = new FileOutputStream(file);
//1、FileOutputStream默认每次写入是覆盖的,可以更改append
//2、如果文件不存在会新建一个
//方法二
FileOutputStream fos = new FileOutputStream("盘符:\\路径\\xxx.txt",true);//append为true就是追加
//开水龙头
byte[] b = data.getBytes(StandardCharsets.UTF_8);//将数据转成字节数组类型
fos.write(b);//需要一个字节数组类型的参数
//关水龙头
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 默认FileOutputStream是覆盖式写入的,可以设置append为true,将覆盖改为追加
文件复制
- 思路:
- 将文件数据读进程序
- 将程序里的数据写回到文件
- 因此需要文件输入流和文件输出流
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class IODemo03 {
public static void main(String[] args) {
try {
//long start = System.currentTimeMillis();//可以看出消耗的时间
//先创建两个输入输出的水管
FileInputStream fis = new FileInputStream("D:\\a.txt");
FileOutputStream fos = new FileOutputStream("F:\\b.txt");
//导入数据(一个一个字节复制)
int ch = 0;
while ((ch=fis.read())!=-1){
//写入数据
fos.write(ch);
}
//另一种导入方法,简单版
//一次性读取多个字节,再一次性写出多个字节
//顺序不能颠倒
// byte[] b1 = new byte[10];
// fis.read(b1);
// fos.write(b1);
//关水(先用后关)
fos.close();
fis.close();
//long end = System.currentTimeMillis();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 两个输入输出流在运行大的文件时效率比较慢,用
字节缓冲输入流
- BufferedInputStream
- 速度快,但还是需要FileInputStream
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
public class IODemo04 {
public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
//小管道
InputStream inputStream = new FileInputStream("D:\\java.mp4");//1.83G
//大管道
BufferedInputStream bis = new BufferedInputStream(inputStream);//需要一个InputStream类型的参数,所以需要一个小管道
//读数据
byte[] b = new byte[1024*1200];//耗时1162ms,比电脑的复制还快,但并不是越大越快
//byte[] b = new byte[1024*1024*1024];//一次读1G,耗时6303ms,反而变慢了
int len = 0;//用于判断是否读完
while ((len=bis.read(b))!=-1){
System.out.println(len);
}
long end = System.currentTimeMillis();
System.out.println("共耗时"+(end-start)+"ms");
bis.close();
//inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 相当于把数据打包成若干个字节数组,一包一包的传,比一个一个字节快多了
- 虽然FileInputStream也可以这样操作,但速度远慢于BufferedInputStream
字节缓冲输入流
- BufferedOutputStream
- 速度快,但也是需要FileOutputStream
实现一下复制,还是刚刚那些代码
import java.io.*;
public class IODemo05 {
public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
InputStream inputStream = new FileInputStream("D:\\java.mp4");//1.83G
BufferedInputStream bis = new BufferedInputStream(inputStream);
OutputStream outputStream = new FileOutputStream("C:\\Users\\yjj\\copy.mp4");
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
//读数据
byte[] b = new byte[1024*1024];
int len = 0;//用于判断是否读完
while ((len=bis.read(b))!=-1){
bos.write(b);
System.out.println(len);
}
long end = System.currentTimeMillis();
System.out.println("共耗时"+(end-start)+"ms");
bos.close();
bis.close();
outputStream.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
字符流
- 字节流能操作所有文件,而字符流操作文本文件比较方便
- 解决了乱码问题
FileReader
- Reader(字符输入流祖宗类)
import java.io.FileReader;
public class ReaderDemo01 {
public static void main(String[] args) {
try {
FileReader fileReader = new FileReader("D:\\1.txt");
char[] c = new char[1024];
int len = 0;
while ((len=fileReader.read(c))!=-1){
String str = new String(c,0,len);//从0开始到len拼接成一个字符串
System.out.println(str);
}
fileReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
FileWriter
- Writer(字符输出流祖宗类)
import java.io.FileWriter;
public class WriterDemo01 {
public static void main(String[] args) {
try {
String str = "感谢b站狂神说、千峰教育、鸟哥教育的免费资源";
//也可以修改append为true变成追加
FileWriter fileWriter = new FileWriter("D:\\3.txt");
fileWriter.write(str);//直接传参,不需要将参数转换成字节数组,相当于偷懒
fileWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 字节流可以做一切
- 字符流里的BufferedReader和BufferedWriter与字节流里的没有太大区别