Java-IO流(二)
文章目录
- IO流-字符流
- 文件字符输入流-读字符数据进来
- 文件字符输出流-写字符数据出去
- IO流-缓冲流
- 字节缓冲流
- 字符缓冲流
- 字符缓冲输入流
- 字符缓冲输出流
- 案例:拷贝某个文件到另一个文件,恢复顺序
- 原始流、缓冲流的性能分析【重点】
- IO流-转换流
- 引出问题:不同编码读取时会乱码
- 字符输入转换流
- 字符输出转换流
- IO流-打印流
- IO流-数据流
- IO流-序列化流
- 补充知识:IO框架
IO流-字符流
文件字符输入流-读字符数据进来
/*** 目标:掌握文件输入流,每次读取一个字符*/
public class FileReaderTest1 {public static void main(String[] args) {//1.创建一个文件字符输入流管道与源文件接通try (Reader fr = new FileReader("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt");){//2.读取文本文件的内容
// int c;//记住每次读取的字符编号
// while ((c = fr.read()) != -1) {
// System.out.print((char) c);
// }//每次读取一个字符的形式,性能肯定是比较差的//3.每次读取多个字符char[] buffer = new char[3];int len;while ((len = fr.read(buffer)) != -1) {//读取多少倒出多少System.out.print(new String(buffer, 0, len));}//性能是比较不错的!}catch(Exception e){e.printStackTrace();}}}
文件字符输出流-写字符数据出去
/*** 目标:掌握文件字符输出流,写字符数据出去*/
public class FileWriterTest2 {public static void main(String[] args) {try (//0.创建一个文件字符输出流管道与目标文件接通//覆盖管道
// Writer fw = new FileWriter("D:\\Code\\JDBC\\IO\\src\\main\\java\\com\\wuxuan\\1.txt",true);//追加数据的管道Writer fw = new FileWriter("Basic\\src\\main\\java\\com\\wuxuan\\IO\\2.txt",true);) {//1.public void write(int c);写一个字符出去fw.write("a");fw.write(97);fw.write('磊');fw.write("\r\n");//2.public void write(String c)写一个字符串出去fw.write("我爱你中国abc");fw.write("\r\n");//3.public void write(String c,int pos ,int len):写字符串的一部分出去fw.write("我爱你中国abc",0,5);fw.write("\r\n");//4.public void write(char[] buffer):写一个字符数组出去char[] buffer = {'无','双','a','b','c','d','e','f'};fw.write(buffer);fw.write("\r\n");//5.public void write(char[] buffer,int pos, int len):写字符数组的一部分出去fw.write(buffer,0,2);fw.write("\r\n");} catch (IOException e) {e.printStackTrace();}}
}
/*** 目标:搞清楚字符输出流使用时的注意事项*/
public class FileWriterTest3 {public static void main(String[] args) throws Exception {//0.创建一个文件字符输出流管道与目标文件接通//覆盖管道
// Writer fw = new FileWriter("Basic\src\main\java\com\wuxuan\IO\1.txt");//追加数据的管道Writer fw = new FileWriter("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt",true);//public void write(int c);写一个字符出去fw.write("a");fw.write(97);fw.write('磊');fw.write("\r\n");// fw.flush();fw.close();}
}
IO流-缓冲流
字节缓冲流
/*** 目标:掌握字节缓冲流的作用*/
public class BufferedInputStreamTest1 {public static void main(String[] args){try (//1.创建一个字节输入流管道与源文件接通InputStream is = new FileInputStream("C:\\Users\\20316\\Desktop\\小A\\2.jpg");//定义一个字节缓冲输入流包装原始的字节输入流InputStream bis = new BufferedInputStream(is,8192*2);//2.创建一个字节输出流管道与目标文件接通OutputStream os = new FileOutputStream("C:\\Users\\20316\\Desktop\\无双微信头像~~~.jpg");//定义一个字节缓冲输出流包装原始的字节输出流OutputStream bos = new BufferedOutputStream(os,8192*2);){//3.创建一个字节数组,负责转移字节数据byte[] bytes = new byte[1024];//1KB//4.从字节输入流中读取字节数据,写出去到字节输出流中,读多少取多少int len ;//记住每次读取了多少字节while((len = bis.read(bytes)) != -1){bos.write(bytes,0,len);}System.out.println("复制成功~无双陛下!");} catch (IOException e) {/*
----------------------------总结对比----------------------------------------
特点 e.printStackTrace(); throw new RuntimeException(e);
功能 打印异常信息到控制台 抛出一个新的异常,封装原始异常
用途 调试阶段快速定位问题 异常封装和传播,让调用者处理
对程序流程的影响 程序继续执行后续代码 当前方法中断,控制权传递给调用者
是否适合生产环境 不适合(可能暴露敏感信息) 适合(但需要调用者处理)
----------------------------最佳实践----------------------------------------
调试阶段:使用 e.printStackTrace(); 快速定位问题。
生产环境:
避免直接打印异常信息到控制台。
使用日志框架(如 Log4j、SLF4J 等)记录异常信息。
使用 throw new RuntimeException(e); 或自定义异常封装原始异常,让调用者根据需要进行处理。
---------------------------------------------------------------------------
*/
// throw new RuntimeException(e);e.printStackTrace();}}
}
字符缓冲流
字符缓冲输入流
/*** 目标:掌握字符缓冲输入流的用法*/
public class BufferedReaderTest2 {public static void main(String[] args) {//1.创建一个文件字符输入流管道与源文件接通try (Reader fr = new FileReader("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt");//创建一个字符缓冲输入流包装原始的字符输入流//注意:这里就不要用多态写法了!// 因为我们要调用BufferedReader新增的功能public String readLine()//读取一行数据返回,如果没有数据可读了,返回nullBufferedReader br = new BufferedReader(fr);){//
// char[] buffer = new char[3];
// int len;
// while ((len = fr.read(buffer)) != -1) {
// //读取多少倒出多少
// System.out.println(new String(buffer, 0, len));
// }
// //性能是比较不错的!String line;while ((line = br.readLine()) != null) {System.out.println(line);}}catch(Exception e){e.printStackTrace();}}
}
字符缓冲输出流
/*** 目标:掌握字符缓冲输出流的用法。*/
public class BufferedWriterTest3 {public static void main(String[] args) {try (Writer fw = new FileWriter("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt", true);// 创建一个字符缓冲输出流管道包装原始的字符输出流BufferedWriter bw = new BufferedWriter(fw);){bw.write('a');bw.write(97);bw.write('磊');bw.newLine();bw.write("我爱你中国abc");bw.newLine();} catch (Exception e) {e.printStackTrace();}}
}
案例:拷贝某个文件到另一个文件,恢复顺序
/*** 目标:恢复文件内容顺序到新文件中*/
public class Demo {public static void main(String[] args) {try (//2.创建缓冲字符输入流管道与源文件接通BufferedReader br = new BufferedReader(new FileReader("Basic\\src\\main\\java\\com\\wuxuan\\IO\\2.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("Basic\\src\\main\\java\\com\\wuxuan\\IO\\3.txt"))){//1,定义一个ArrayList集合存储每段内容List<String> data = new ArrayList<String>();//3.按照行读取每段String line;while((line = br.readLine()) != null){data.add(line);}//4.对List集合中的每段文章进行排序Collections.sort(data);System.out.println(data);//5.遍历List集合的每段内容,依次写出去到新文件中for (String ln : data) {bw.write(ln);bw.newLine();//换行}} catch (Exception e) {e.printStackTrace();}}
}
原始流、缓冲流的性能分析【重点】
/**目标:观察原始流和缓冲流的性能。*/
public class TimeTest4 {// 复制的视频路径private static final String SRC_FILE = "C:\\Users\\20316\\Desktop\\技术学习\\01-版本控制Git\\19_学习目标.mp4";// 复制到哪个目的地private static final String DEST_FILE = "C:\\Users\\20316\\Desktop\\技术学习\\IO\\";public static void main(String[] args) {copy01(); // 低级字节流一个一个字节的赋值,慢的简直让人无法忍受,直接淘汰!copy02();// 低级的字节流流按照一个一个字节数组的形式复制,速度较慢!copy03(); // 缓冲流按照一个一个字节的形式复制,速度较慢,直接淘汰!copy04(); // 缓冲流按照一个一个字节数组的形式复制,速度极快,推荐使用!}private static void copy01() {long startTime = System.currentTimeMillis();try (InputStream is = new FileInputStream(SRC_FILE);OutputStream os = new FileOutputStream(DEST_FILE + "1.mp4");){int b;while ((b = is.read()) != -1){os.write(b);}}catch (Exception e){e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("低级字节流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");}private static void copy02() {long startTime = System.currentTimeMillis();try (InputStream is = new FileInputStream(SRC_FILE);OutputStream os = new FileOutputStream(DEST_FILE + "2.mp4");){byte[] buffer = new byte[1024*64];//1KBint len;while ((len = is.read(buffer)) != -1){os.write(buffer, 0, len);}}catch (Exception e){e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("低级字节流使用字节数组复制耗时:" + (endTime - startTime) / 1000.0 + "s");}private static void copy03() {long startTime = System.currentTimeMillis();try (InputStream is = new FileInputStream(SRC_FILE);BufferedInputStream bis = new BufferedInputStream(is);OutputStream os = new FileOutputStream(DEST_FILE + "3.mp4");BufferedOutputStream bos = new BufferedOutputStream(os);){int b;while ((b = bis.read()) != -1){bos.write(b);}}catch (Exception e){e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("缓冲流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");}private static void copy04() {long startTime = System.currentTimeMillis();try (InputStream is = new FileInputStream(SRC_FILE);BufferedInputStream bis = new BufferedInputStream(is, 64 * 1024);OutputStream os = new FileOutputStream(DEST_FILE + "4.mp4");BufferedOutputStream bos = new BufferedOutputStream(os, 64 * 1024);){byte[] buffer = new byte[1024 * 64]; // 32KBint len;while ((len = bis.read(buffer)) != -1){bos.write(buffer, 0, len);}}catch (Exception e){e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("缓冲流使用字节数组复制耗时:" + (endTime - startTime) / 1000.0 + "s");}
}
IO流-转换流
引出问题:不同编码读取时会乱码
/*** 目标:掌握不同编码读取乱码的问题*/
public class Test1 {public static void main(String[] args) {try (//1.创建一个文件字符输入流与源文件接通//代码编码:UTF-8 文件的编码:UTF-8
// Reader fr = new FileReader("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt");// 1 床 前 明 月 光// GBK o [oo] [oo] [oo] ...// UTF-8 1 ?????//代码编码:UTF-8 文件的编码:GBKReader fr = new FileReader("Basic\\src\\main\\java\\com\\wuxuan\\IO\\3.txt");//2.把文件字符输入流包装成缓冲字符输入流BufferedReader br = new BufferedReader(fr);){String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (Exception e) {throw new RuntimeException(e);}}
}
字符输入转换流
/*** 目标:掌握字符输入转换流的作用*/
public class InputStreamReaderTest2 {public static void main(String[] args) {try (//1,得到文件的原始字节流(GBK的字节流形式)InputStream is = new FileInputStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\3.txt");//2.把原始的字节输入流按照指定的字符集编码转换成字符输入流Reader isr = new InputStreamReader(is,"GBK");//3.把字符输入流包装成缓冲字符输入流BufferedReader br = new BufferedReader(isr);){String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (Exception e) {e.printStackTrace();}}
}
字符输出转换流
/*** 目标:掌握字符输出转换流的作用*/
public class OutputStreamReaderTest3 {public static void main(String[] args) {try (//1,得到文件的原始字节流(GBK的字节流形式)OutputStream os = new FileOutputStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\4.txt");//2.把原始的字节输出流按照指定的字符集编码转换成字符输入流Writer osw = new OutputStreamWriter(os,"GBK");//3.把字符输出流包装成缓冲字符输入流BufferedWriter bw= new BufferedWriter(osw);){bw.write("我是中国人");bw.write("我爱妈咪!!!");} catch (Exception e) {e.printStackTrace();}}
}
IO流-打印流
package com.wuxuan.IO.printstream;import java.io.*;
import java.nio.charset.Charset;/*** 目标:掌握打印流:PrintStream/PrintWriter的用法*/
public class PrintTest1 {public static void main(String[] args) {try (//1.创建一个打印流管道
// PrintStream ps = new PrintStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\printText.txt", Charset.forName("GBK"));
// PrintStream ps = new PrintStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\printText.txt");
// PrintWriter ps = new PrintWriter("Basic\\src\\main\\java\\com\\wuxuan\\IO\\printText.txt");//高级流没有追加数据,想要追加数据就采用以下方式PrintWriter ps = new PrintWriter(new FileWriter("Basic\\src\\main\\java\\com\\wuxuan\\IO\\printText.txt"),true);){ps.println(97);ps.println('a');ps.println("我爱你中国abc");ps.println(true);ps.println(99.5);ps.write(97);//'a'} catch (Exception e) {e.printStackTrace();}}
}
package com.wuxuan.IO.printstream;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;/*** 目标:了解下输出语句的重定向*/
public class PrintTest2 {public static void main(String[] args) {System.out.println(1);System.out.println(2);try (PrintStream ps = new PrintStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\printText.txt");){System.setOut(ps);System.out.println(3);System.out.println(4);} catch (Exception e) {e.printStackTrace();}}
}
IO流-数据流
/*** 目标:数据输出流*/
public class DataOutputStreamTest1 {public static void main(String[] args) {try (//1.创建一个数据输出流包装低级的字节输出流DataOutputStream dos = new DataOutputStream(new FileOutputStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\data.txt"));){dos.writeInt(97);dos.writeDouble(99.5);dos.writeBoolean(true);dos.writeUTF("我是无双大帝!!!");} catch (Exception e) {throw new RuntimeException(e);}}
}
/*** 目标:使用数据输入流读取特定类型的数据*/
public class DataInputStreamTest2 {public static void main(String[] args) {try (DataInputStream dis = new DataInputStream(new FileInputStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\data.txt"));){int i = dis.readInt();double d = dis.readDouble();boolean b = dis.readBoolean();String rs = dis.readUTF();System.out.println(i);System.out.println(d);System.out.println(b);System.out.println(rs);} catch (Exception e) {throw new RuntimeException(e);}}
}
IO流-序列化流
package com.wuxuan.IO.object_stream;import java.io.Serializable;//注意:对象如果需要序列化,必须实现序列化接口
public class User implements Serializable {private String loginName;private String userName;private int age;//transient 这个成员变量将不参与序列化private transient String password;public User() {}public User(String loginName, String userName, int age, String password) {this.loginName = loginName;this.userName = userName;this.age = age;this.password = password;}public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"loginName='" + loginName + '\'' +", userName='" + userName + '\'' +", age=" + age +", password='" + password + '\'' +'}';}
}
package com.wuxuan.IO.object_stream;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;/*** 目标:掌握对象字节输出流的使用:序列化对象*/
public class Test1 {public static void main(String[] args) {try (//2.创建一个对象字节输出流包装原始的字节输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\object.txt"))){//1.创建一个Java对象User u = new User("admin","无双",18,"123456");//3.序列化对象到文件中去oos.writeObject(u);System.out.println("序列化对象成功!");} catch (IOException e) {throw new RuntimeException(e);}}
}
package com.wuxuan.IO.object_stream;import java.io.*;/*** 目标:掌握对象字节输入流的使用:反序列化对象*/
public class Test2 {public static void main(String[] args) {try (//2.创建一个对象字节输入流包装低级的字节输入流与源文件接通ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Basic\\src\\main\\java\\com\\wuxuan\\IO\\object.txt"))){User u = (User)ois.readObject();System.out.println(u);System.out.println("序列化对象成功!");} catch (Exception e) {throw new RuntimeException(e);}}
}
补充知识:IO框架
package com.wuxuan.commons_io;import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;/*** 目标:使用CommonsIO框架进行IO相关的操作*/
public class CommonsIOTest1 {public static void main(String[] args) throws Exception {FileUtils.copyFile(new File("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt"),new File("Basic\\src\\main\\java\\com\\wuxuan\\IO\\a.txt"));FileUtils.copyDirectory(new File("C:\\Users\\20316\\Desktop\\小A\\Copy1"),new File("C:\\Users\\20316\\Desktop\\小A\\Copy2"));FileUtils.deleteDirectory(new File("C:\\Users\\20316\\Desktop\\小A\\Copy2"));//Java提供的原生的一行代码搞定很多事情
// Files.copy(Path.of("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt"),Path.of("Basic\\src\\main\\java\\com\\wuxuan\\IO\\999.txt"));System.out.println(Files.readString(Path.of("Basic\\src\\main\\java\\com\\wuxuan\\IO\\1.txt")));}
}