一.字节流(以字节为单位进行数据传输)
输出流 OutputStream
程序-->文件(写文件使用输出流)
输入流 InputStream
文件-->程序 (读文件使用输入流)
注意:以上两个抽象类是所有字节流的父类写文件的步骤:
1.创建要绑定的文件
2.创建输出流 绑定文件
3.写文件
4.关闭资源流
字节输出流:
//给输出流绑定一个输出文件
//给出路径 可以没有该文件 系统会帮你创建出来
File file=new File("/Users/lanou/Desktop/aa/aa.txt");
//创建文件字节输出流
FileOutputStream fos=new FileOutputStream(file);
//写文件
//注意 流这块全是抛的IOException
//传入int值得方法 按ACSII输入 一次写入一个字节
fos.write(49);
fos.write(55);
fos.write(55);
//创建字节数组
byte[]b= {66,87,68};
fos.write(b);
//直接写字符串
//字符串转字节数组 getBytes()
//字节数组赚字符串 字符串的构造方法
fos.write("wanglong".getBytes());
fos.write(b,1,2);
//关闭资源
fos.close();
}
File file=new File("/Users/lanou/Desktop/aa/aa.txt");
//创建空的引用
FileOutputStream fos=null;
try {
fos=new FileOutputStream(file);
fos.write("haha".getBytes());
} catch (FileNotFoundException e) {
//文件找不到 再向下操作无意义
//停止程序 修改代码
//抛个运行时异常 提示信息 停止程序
throw new RuntimeException("文件找不到");
} catch (IOException e) {
//写入失败
throw new RuntimeException("写入失败");
}finally {
//非空判断 (fos创建成功 的情况下关闭)
if (fos!=null) {
//关闭资源时 一定要确保关闭的代码可以执行
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
}
}
}
字节输入流:
//循环读取(一次只能读一个字节)
int num=0;
while ((num=fis.read())!=-1) {
System.out.println((char)num);
}
fis.close();
int num=0;
byte[] b= new byte[2];
//判断读取的变量
while ((num=fis.read(b))!=-1) {
//直接使用string的构造方法 将字节数组转化成字符串
System.out.print(new String(b, 0, num));
文件续写:
File file =new File("/Users/lanou/Desktop/aa/xuxie.txt");
//利用构造方法参数进行续写(布尔参数)
//mac换行 \n windows\r\n
FileOutputStream fos=new FileOutputStream(file,true);
fos.write("wanglong\n".getBytes());
fos.write("nihao\n".getBytes());
fos.close();
}
使用字节流 进行文件的复制需要异常处理:
//被读文件
File file1 =new File("/Users/lanou/Desktop/aa/蓝鸥实训生手册.pdf");
//写入文件
File file2 =new File("/Users/lanou/Desktop/aa/lanou.pdf");
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream(file1);
fos=new FileOutputStream(file2);
// 读写
int num=0;
while ((num=fis.read())!=-1) {
//写
fos.write(num);
}
// int len=0;
// byte[]b=new byte[1024];
// while ((len=fis.read(b))!=-1) {
// fos.write(b, 0, len);
// }
} catch (FileNotFoundException e) {
throw new RuntimeException("文件找不到");
}catch (Exception e2) {
throw new RuntimeException("读取失败");
}
finally {
//进行流的关闭
if (fis!=null) {
try {
fis.close();
}
catch (Exception e2) {
throw new RuntimeException("关闭失败");
}finally {
//进行流的关闭
if (fis!=null) {
try {
fos.close();
}
catch (Exception e2) {
throw new RuntimeException("关闭失败");
}
}
}
}
}
将一个文件夹 复制 到另一个文件夹下:
//参数
//1.源文件(被复制的文件)src
//2.目标文件(复制到那个文件夹下)dest
public static void copyDir(File src ,File dest) throws IOException {
//去目标文件夹下创建一个文件夹出来
//新文件夹的名字是源文件的名字 路径是目标文件的路径
File newfile=new File(dest,src.getName());
newfile.mkdir();
File[] files = src.listFiles();
for (File subfile : files) {
if (subfile.isFile()) {
FileInputStream fis=new FileInputStream(subfile);
//创建一个要写入的文件(拼接文件名字)
File tempfile=new File(newfile,subfile.getName());
FileOutputStream fos=new FileOutputStream(tempfile);
//读写
int len=0;
byte[]b= new byte[1024];
while ((len=fis.read(b))!=-1) {
fos.write(b, 0, len);
}
fis.close();
fos.close();
}else {
//继续遍历
copyDir(subfile, newfile);
}
}
}
将一个文件夹下的所有txt文件 复制 到另一个文件夹下并且保存为.java文件
//构建写的路径
String name = subfile.getName();
String[] split = name.split("\\.");
//构建写入的文件
File file=new File(dest,split[0]+".java");
二.字符流
Writer 写 字符输出流
Reader 读 字符输入流
写:
//创建一个文件字符输出流
File file =new File("/Users/lanou/Desktop/aa/dongdong.txt");
FileWriter fWriter=new FileWriter(file);
//写
fWriter.write(65);
//刷新 相当于写入的时候 有一个缓冲区
//写的字符是先写到缓冲区 刷新时 才会将写的字符全部写入到文件中
//建议写一次刷新一次
fWriter.flush();
//利用字符数组写入
char[]c= {'x','w','t','m'};
fWriter.write(c);
fWriter.flush();
//利用字符串写入
fWriter.write("hahahah\n");
fWriter.write("haha\n");
fWriter.flush();
//关闭资源
//关闭流资源之前 自动刷新缓冲区
fWriter.close();
}
读:
File file =new File("/Users/lanou/Desktop/aa/dongdong.txt");
FileReader fileReader=new FileReader(file);
//单个字符
// int num=0;
// while ((num=fileReader.read())!=-1) {
// System.out.println((char)num);
// }
//利用缓冲数组
int len=0;
char []c=new char[1024];
while ((len=fileReader.read(c))!=-1) {
//字符数组转字符串
System.out.println(new String(c, 0, len));
}
三.转化流(可以查询对应编码表)
转换流可以根据你想要的编码格式进行读写
读写时可以设置编码格式
OutputStreamWriter(字符流专项字节流的桥梁)
1.程序中写入字符时,先使用转换流 根据想查询的码表格式去查询
2.如果查的是gbk格式 那么一个中文字符就查到两个字节的字节编码
3.这个字节最后给到了构建转换流时传入的字节流
4.通过这个字节流 按字节写入到文件中
InputStreamReader(读取文件 字节流通向字符流的桥梁)
1.按字节读取文件 将字节编码给到转换流
2.如果UTF-8需要3个字节
3.只用字符流读取到程序中
转换流与子类有什么区别
子类(FileWriter /FileReader)只能以默认的字符编码格式读写
父类(转化流) 可以这只字符的编码格式
按GBK写public static void getGBK() throws IOException {
FileOutputStream fos=new FileOutputStream("/Users/lanou/Desktop/aa/GBK.txt");
OutputStreamWriter osw=new OutputStreamWriter(fos,"gbk");
osw.write("张三");
osw.close();
按GBK读
public static void getAnotherGBK() throws IOException {
FileInputStream fis=new FileInputStream("/Users/lanou/Desktop/aa/GBK.txt");
InputStreamReader isr=new InputStreamReader(fis,"GBK");
int len=0;
char[]c=new char[1024];
while ((len=isr.read(c))!=-1) {
System.out.println(new String(c, 0, len));
}
isr.close();
}
四.缓冲流(高效流)
内部自带一个缓冲区(字节数组)
BufferedOutputStream(写文件) 缓冲字节输出流
BufferedInputStream(读文件) 缓冲字节输入流
写:
FileOutputStream fos=new FileOutputStream("/Users/lanou/Desktop/aa/guifen.txt");
//构建一个缓冲流写文件
BufferedOutputStream bos=new BufferedOutputStream(fos);
//写
bos.write("guifen".getBytes());
bos.close();
读:
FileInputStream fis=new FileInputStream("/Users/lanou/Desktop/aa/guifen.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
//读
int len=0;
byte[]b=new byte[1024];
while ((len=bis.read(b))!=-1) {
System.out.println(new String(b, 0, len));
}
bis.close();