前言
IO流:数据传输的通道,通过流的方式读写文件,流是指一连串流动的字节/字符
流按流动方向可分为:输入/输出流 (注:输入/输出流是相对于计算机内存,数据源和目标)
流按数据单元可分为:字节/字符流
字节流
demo
public static void main(String[] args) { //计时器,hutool工具类 TimeInterval timer = DateUtil.timer(); byteFilecopy(); System.out.println("\n操作完成,耗时:"+timer.intervalMs()+"(毫秒)"); } /* 字节流,实现非文本文件的复制粘贴 文本文件不建议使用字节流操作,因为中文字符占两个字节,如果正好被分割就会出现乱码 */ public static void byteFilecopy(){ final String srcFile = "F:\\logo.png";//源文件 final String targetFile = "F:\\logo1.png";//目标文件 //除了从文件中读取,也可以使用ByteArrayInputStream直接读取 try(FileInputStream inputStream = new FileInputStream(srcFile); FileOutputStream outputStream = new FileOutputStream(targetFile,false);) { byte[] chars = new byte[1024];//缓存区大小,有初始化0值 int length; while ((length = inputStream.read(chars)) != -1) { //写入,写入部分数组 outputStream.write(chars, 0, length);//如果写入完整数组,会将未被填充的0值也一起写入 } //刷新输入流 outputStream.flush(); } catch (IOException e) { System.err.println("操作失败..."); e.printstacktrace(); } }
字节流,使用ObjectOutputStream保存、读取java对象
public static void main(String[] args) { //计时器,hutool工具类 TimeInterval timer = DateUtil.timer(); javaObject(); System.out.println("\n操作完成,耗时:"+timer.intervalMs()+"(毫秒)"); } /* 字节流,使用ObjectOutputStream保存、读取java对象 */ public static void javaObject(){ final String targetFile = "F:\\User.txt";//目标文件 //写入 try(ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(targetFile,false));) { final HashMap<String, Object> hashMap = new HashMap<>(4); hashMap.put("id","00001"); hashMap.put("age",18); hashMap.put("name","张三"); hashMap.put("addTime",new Date()); outputStream.writeObject(hashMap); //刷新输入流 outputStream.flush(); } catch (IOException e) { System.err.println("操作失败..."); e.printstacktrace(); } //读取 try(ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(targetFile))) { Object object = inputStream.readobject(); //打印 System.out.println(object); } catch (IOException | ClassNotFoundException e) { System.err.println("操作失败..."); e.printstacktrace(); } }
字符流
demo
字符流,实现文本文件的复制粘贴
PS:txt小说从知轩藏书下载
public static void main(String[] args) { //计时器,hutool工具类 TimeInterval timer = DateUtil.timer(); charFilecopy(); System.out.println("\n操作完成,耗时:"+timer.intervalMs()+"(毫秒)"); } /* 字符流,实现文本文件的复制粘贴 文本文件处理不建议使用FileReader、FileWriter,这两个对象使用默认系统编码,并且不能手动设置,读取和写入文件都应与源文件编码一致,否则会乱码 */ public static void charFilecopy(){ final String charsetName = "GBK";//ANSI编码,可用GBK读取 final String srcFile = "F:\\《凡人修仙传》(校对版全本+番外)作者:忘语.txt";//源文件 final String targetFile = "F:\\《凡人修仙传》.txt";//目标文件 //try-catch语法糖 try(InputStreamReader reader = new InputStreamReader(new FileInputStream(srcFile), charsetName); OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(targetFile), charsetName);) { char[] chars = new char[1024];//缓存区大小,有初始化null值 int length; while ((length = reader.read(chars)) != -1) { //打印 //System.out.print(new String(chars, 0, length)); //写入,写入部分数组 writer.write(chars, 0, length);//如果写入完整数组,会将未被填充的null值也一起写入 } //刷新输入流 writer.flush(); } catch (IOException e) { System.err.println("操作失败..."); e.printstacktrace(); } }
字符流,BufferedReader读取
public static void main(String[] args) { //计时器,hutool工具类 TimeInterval timer = DateUtil.timer(); charRead(); System.out.println("\n操作完成,耗时:"+timer.intervalMs()+"(毫秒)"); } /* 字符流,BufferedReader读取 BufferedReader,自带缓冲区可方便的读取整行 */ public static void charRead(){ //直接读取 try(BufferedReader reader = new BufferedReader(new ChararrayReader("人民英雄永垂不朽!\nheroes immortal!\n你好世界,Hello Java".tochararray()),1024);) { //从文件读取 //try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("F:\\test.txt"), "UTF-8"),1024);) { //1、read读取 char[] chars = new char[1024];//缓存区大小,有初始化null值 int length; while ((length = reader.read(chars)) != -1) { //打印 System.out.print(new String(chars, 0, length)); } //2、readLine读取 String line; while((line = reader.readLine()) != null) { //打印,补回换行符 System.out.print(line+"\n"); } //3、转成Stream,再进行操作 reader.lines().forEach((line1)->{ //打印,补回换行符 System.out.print(line1+"\n"); }); //经测试,以上三种方式结果一致 } catch (IOException e) { System.err.println("操作失败..."); e.printstacktrace(); } }
更新
public static void main(String[] args) { String path = "E:\\abc";//文件夹 //循环删除所有文件、文件夹 deleteallFile(new File(path)); //然后在创建新空文件夹 new File(path).mkdir(); System.out.println("操作完成!"); }
//递归删除所有文件 private static void deleteallFile(File file){ if (file.isFile()) { file.delete(); } else if (file.isDirectory()) { for (File listFile : Objects.requireNonNull(file.listFiles())) { deleteallFile(listFile); } file.delete(); } }
后记
要点:
1、文本文件建议使用字符流操作,因为中文字符占两个字节,用字节流如果正好被分割就会出现乱码
2、文本文件处理不建议使用FileReader、FileWriter,这两个对象使用默认系统编码,并且不能手动设置,读取和写入文件都应与源文件编码一致,否则会乱码;读取文本使用BufferedReader操作,自带缓冲区可方便的读取整行
3、使用ObjectOutputStream来保存、读取java对象,利用好了可以实现骚操作(自行扩展)
Java基础之IO流暂时先记录到这,后续再进行补充