目录
IO流拷贝文件
我们会展示两种IO流拷贝文件的方式,一种是简单且标准的,需要能背下的,一种是升级版,可以在拷贝文件的时候显示拷贝的进度条,从百分之一到百分之百。
简单且标准的:
实际代码不多,大部分都是try catch
/**
* 拷贝文件
* 把一个文件拷贝到另一个地方
*/
@Test
public void copyFiel(){
// 定义文件输入、输出的变量
InputStream inputStream = null;
OutputStream outputStream = null;
try {
// 文件输入和输出的位置,必须具体到文件名,否则报错
inputStream = new FileInputStream("E://版权音乐/付费/音乐任务组_20200227_1704/梦里之二-钢琴版.mp3");
outputStream = new FileOutputStream("E://音效文件/梦里之二-钢琴版.mp3");
// 把文件传输大小放入byte数组中
byte[] buffer = new byte[1024];
// 当桶等于输入文件读取的大小且不等于-1时,进入这个循环,读取的大小是buffer
inputStream.read(buffer);
// 输出文件写入的速度是buffer,从0开始读,每次读len这个长度,不加后面的0,len都可以,但是有时候会复制出错
outputStream.write(buffer,0,len);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 如果输入不等于空
if (inputStream != null){
try {
//输入关闭,不关闭会浪费内存,导致卡顿
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 如果输出不等于空
if (outputStream != null){
try {
//输出关闭
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
升级版有进度条的:
/**
* 拷贝文件
* 把一个文件拷贝到另一个地方
*/
@Test
public void copyFiel(){
// 定义文件输入、输出的变量
InputStream inputStream = null;
OutputStream outputStream = null;
try {
// 定义一个文件,确定输入文件的位置
File file = new File("E://版权音乐/付费/音乐任务组_20200227_1704/梦里之二-钢琴版.mp3");
// 文件输入和输出的位置,必须具体到文件名,否则报错
inputStream = new FileInputStream("E://版权音乐/付费/音乐任务组_20200227_1704/梦里之二-钢琴版.mp3");
outputStream = new FileOutputStream("E://音效文件/梦里之二-钢琴版.mp3");
// 定义输入文件的长度
long length = file.length();
// 文件传输一次的大小,20K
int per = 1024 * 20;
// 初始化文件完成度
long complete = 0;
// 把文件传输大小放入byte数组中
byte[] buffer = new byte[per];
// 定义一个桶,用来当做文件传输的中转站
int len;
// 当桶等于输入文件读取的大小且不等于-1时,进入这个循环,读取的大小是buffer
while ((len = inputStream.read(buffer)) != -1){
// 完成度加上一个per
complete += per;
// 输出文件写入的速度是buffer,从0开始读,每次读len这个长度,不加后面的0,len都可以,但是有时候会复制出错
outputStream.write(buffer,0,len);
// 初始化已经完成的进度
long currentProgress = 0;
// 进度等于已经完成度除以文件的长度,并且把这个数值再*100,这样就能算百分比了,Math.round是四舍五入
long progress = Math.round((float)complete/length * 100);
// 当进度不等于已经完成的进度且小于等于100时,输出语句。至于设置小于等于100,是因为有时候会出来101,那就尴尬了
if (progress != currentProgress && progress <= 100){
System.out.println("已经拷贝了:" + progress + "%");
}
//完成的进度等于进度
currentProgress = progress;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 如果输入不等于空
if (inputStream != null){
try {
//输入关闭,不关闭会浪费内存,导致卡顿
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 如果输出不等于空
if (outputStream != null){
try {
//输出关闭
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
IO流读文件
字节流读文件
/**
* 字节流读文件内容,字节流可以处理字符流的任何东西
*/
@Test
public void readFile() throws Exception{
InputStream inputStream = new FileInputStream("C://Users/86151/Desktop/新建文本文档.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1){
String s = new String(buffer, 0, len);
System.out.println(s);
}
inputStream.close();
}
字符流读文件
/**
* 字符流读文件内容
*/
@Test
public void readFile2() throws Exception{
Reader reader = new FileReader("C://Users/86151/Desktop/新建文本文档.txt");
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) != -1){
String s = new String(buffer, 0, len);
System.out.println(s);
}
reader.close();
}
处理流读文件
/**
* 处理流读文件内容
*/
@Test
public void readFile3() throws Exception{
Reader reader = new FileReader("C://Users/86151/Desktop/新建文本文档.txt");
BufferedReader bf = new BufferedReader(reader);
String str;
// 一下读一行
while ((str = bf.readLine()) != null){
System.out.println(str);
}
reader.close();
}
IO流写文件
字节流写文件
/**
* 字节流写文件
*/
@Test
public void writeFile() throws Exception{
// 怼一根管道到文件上
FileOutputStream fileOutputStream = new FileOutputStream("C://Users/86151/Desktop/新建文本文档.txt");
String str = "hello world";
// 写出去
fileOutputStream.write(str.getBytes());
fileOutputStream.flush();
fileOutputStream.close();
}
字符流写文件
/**
* 字符流写文件
*/
@Test
public void writeFile2() throws Exception{
// 怼一根管道到文件上
FileWriter file = new FileWriter("C://Users/86151/Desktop/新建文本文档.txt");
String str = "hello world2";
// 写出去
file.append("aa").append("bb").append("\n");
file.write(str);
file.flush();
file.close();
}
缓冲流写文件
/**
* 缓冲流写文件
*/
@Test
public void writeFile3() throws Exception{
// 怼一根管道到文件上
FileWriter file = new FileWriter("C://Users/86151/Desktop/新建文本文档.txt");
BufferedWriter bw = new BufferedWriter(file);
String str = "hello world2";
// 写出去
bw.append("aa").append("bb");
bw.write(str);
bw.flush();
bw.close();
file.close();
}
打印流写文件
/**
* 打印流写文件,这个需要在main方法中,不然运行不出来
*/
public static void main(String[] args) throws Exception{
// 怼一根管道到文件上
// 加true表示原来的文件内容继续存在,我们在后面继续追加内容
FileWriter file = new FileWriter("C://Users/86151/Desktop/新建文本文档.txt",true);
PrintWriter printWriter = new PrintWriter(file);
Scanner scanner = new Scanner(System.in);
// 写出去
String flag = null;
while (!"exit".equals(flag)){
flag = scanner.next();
printWriter.println(flag);
file.flush();
}
file.close();
printWriter.close();
}
对象流序列化
/**
* 对象流序列化
* Serializable 是序列化的意思
* 保存成二进制文件,打开看到的是乱码
*/
@Test
public void testObject() throws Exception{
FileOutputStream fileOutputStream = new FileOutputStream("D://ab.temp");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
Users users = new Users();
users.setUsername("弯弯月亮");
users.setDog(new Dog());
objectOutputStream.writeObject(users);
objectOutputStream.flush();
objectOutputStream.close();
fileOutputStream.close();
}
Users.java
public class Users implements Serializable {
private String username;
private Dog dog;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
Dog.java
public class Dog implements Serializable {
}
对象流反序列化
/**
* 反序列化
* 就是把序列化存进去的0和1变成我们一开始存进去的文字和数据
*/
@Test
public void testObject2() throws Exception{
FileInputStream file = new FileInputStream("D://ab.temp");
ObjectInputStream object = new ObjectInputStream(file);
Users users = (Users) object.readObject();
System.out.println(users.getUsername());
object.close();
}