字节流 又称 万能流 不但可以读写文本,还可以读写图片 音频 视频
使用字节流进行 文件的复制
需要对异常进行处理 且计算复制时间
long start = System.currentTimeMillis();
// 被读文件
File file1 = new File("/Users/lanou/Desktop/lna/抽奖系统案例.pdf");
// 写入文件
File file2 = new File("/Users/lanou/Desktop/lna/抽奖.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);
}
} catch (FileNotFoundException e) {
throw new RuntimeException("文件找不到");
} catch (IOException e) {
throw new RuntimeException("读写失败");
}
finally {
// (进行流关闭) 先关哪个都行(读写完毕)
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
}
}
}
}
}
// 结束事件
long stop = System.currentTimeMillis();
System.out.println(stop - start);
File file = new File("/Users/lanou/Desktop/lna/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();
需要进行 递归 遍历
参数
1.源文件(要被复制的文件) src
2.目标文件(复制到哪个文件夹下) dest
public static void copyDir(File src,File dest) throws IOException {
// 去目标文件夹下 创建一个文件夹出来
// 新文件夹的名字 是源文件的名字
// 路径是 目标文件的路径
File newFile = new File(dest, src.getName());
newFile.mkdir();
// 遍历 src
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 num = 0;
byte[] b = new byte[1024];
while ((num=fis.read(b)) != -1) {
// 写
fos.write(b,0,num);
}
fis.close();
fos.close();
} else {
// 文件夹就遍历
copyDir(subfile, newFile);
}
}
}
将一个文件夹下的所有txt文件 复制到
另一个文件夹下并且保存为.java文件
需要用到过滤器
// 过滤器
class getTxt implements FileFilter {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()) {
return true;
}
return pathname.getName().endsWith("txt");
}
}
主要实现方法
public static void copyTxt(File src,File dest) throws IOException {
// 遍历源文件
//File newFile = new File(dest, src.getName());
File[] files = src.listFiles(new getTxt());
for (File subFile : files) {
if (subFile.isFile()) {
FileInputStream fis = new FileInputStream(subFile);
// 构建写的路径
String name = subFile.getName();
String[] split = name.split("\\.");
// 构建写入的文件
File temp = new File(dest, split[0]+".java");
FileOutputStream fos = new FileOutputStream(temp); // 创建写的输出流
// 读
int len = 0;
byte[] b = new byte[1024];
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
fis.close();
fos.close();
} else {
// 继续遍历
copyTxt(subFile, dest);
}
}
}
测试
public static void main(String[] args) throws IOException {
File file1 = new File("/Users/lanou/Desktop/lna");
File file2 = new File("/Users/lanou/Desktop/haha");
copyTxt(file1, file2);
}
技巧: 找准读写文件的路径 就一路畅通
基本的编码格式
Mac 默认使用utf-8格式(通用编码格式)
一个中文字符 占3个字节
Windows 默认使用的是GBK格式(简体中文格式)
一个中文字符 占2个字节
Writer (写文件) 字符输出流
Reader (读文件) 字符输入流
这两个类 是所有字符流的父类(抽象类)
public static void main(String[] args) throws IOException {
// 创建一个文件字符输出流
File file = new File("/Users/lanou/Desktop/lna/dongdong.txt");
FileWriter fw = new FileWriter(file);
// 写
fw.write(65);
// 刷新
// 相当于 写入的时候有一个缓冲区
// 写的字符 实际上是 先写入到缓冲区
// 刷新时 才会将写的字符全部写入到文件中
// 建议: 写一次刷新一次
fw.flush();
// 利用字符数组写入
char[] c = {'x','w','t','m'};
fw.write(c);
fw.flush();
fw.write("\n");
// 利用字符串写入
fw.write("人生若只如初见\n");
fw.write("何事秋风悲画扇\n");
// 关闭流资源
// 关闭流资源之前 会自动刷新缓冲区
fw.close();
}
字符流的两种读取方式
File file = new File("/Users/lanou/Desktop/lna/dongdong.txt");
FileReader fr = new FileReader(file);
// 单个字符读
/*
int num = 0;
while ((num = fr.read()) != -1) {
System.out.print((char)num);
}
*/
// 利用缓冲数组读
char[] c = new char[1024];
int len = 0; // 有效个数
while ((len = fr.read(c)) != -1) {
// 字符数组 转 字符串
System.out.println(new String(c, 0, len));
}
fr.close();
通过字符流 复制文件
注意: 字符流只支持读写文档类
public static void main(String[] args) throws IOException {
// 被读文件
File file1 =new File("/Users/lanou/Desktop/lna/dongdong.txt");
// 写入文件
File file2 = new File("/Users/lanou/Desktop/lna/binbin.txt");
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(file1);
fw = new FileWriter(file2);
// 读写
// int num = 0;
// while ((num = fr.read()) != -1) {
// fw.write(num);
// }
int len = 0;
char[] c = new char[1024];
while ((len = fr.read(c)) != -1) {
fw.write(c, 0, len);
// 刷新
fw.flush();
}
} catch (FileNotFoundException e) {
throw new RuntimeException("文件找不到");
} catch (IOException e) {
throw new RuntimeException("读写失败");
}
finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
}
}
}
}
}
}
OutputStreamWriter(字符流通向字节流的桥梁)
1.程序中写入字符时 先使用转换流 根据转换流想查询的码表格式 去查询
2.如果查的是GBK格式 那么一个中文字符
就查到了两个字节的 字节编码
3.这个字节最后给到了 构建转换流时 传入的字节流
4.通过这个字节流 按字节写入到文件中
转换流: 可以查询对应编码表
转换流可以根据你想要的编码格式 进行读写
读写时 可以设置编码格式
构造方法(不传编码格式 默认使用的系统的编码格式)
1.需要一个字节输出流
2.编码格式的名字(utf-8 , gbk 不区分大小写)
InputStreamReader(读取文件 字节流通向字符流的桥梁)
1.按字节读取文件 将字节编码给到转换流
2.如果是utf-8的 需要3个字节
3.使用字符流读取到程序中
// 按GBK格式写入文件
public static void getGBK() throws IOException {
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/lna/GBK.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
osw.write("哈喽");
osw.close();
}
// 按默认UTF8格式读文件
public static void readUTF8() throws IOException {
// 创建一个字节输入流
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/lna/UTF8.txt");
InputStreamReader isr = new InputStreamReader(fis);
int len = 0;
while ((len = isr.read()) != -1) {
System.out.println((char)len);
}
}
内部自带了一个缓冲区(字节数组)
BufferedOutputStream(写文件) 缓冲字节输出流
从程序中一个一个的写入缓冲数组中 通过字节输出流写到文件中
BufferedInputStream(读文件) 缓冲字节输入流
通过文件字节输入流进行读取 一个字节一个字节的读 读进缓冲流的数组中