Java之字符流的详细解析(1):https://developer.aliyun.com/article/1393179
1.续写和换行:操作类似于FileOutputStream。
public class FWWrite { public static void main(String[] args) throws IOException { // 使用文件名称创建流对象,可以续写数据 FileWriter fw = new FileWriter("fw.txt",true); // 写出字符串 fw.write("黑马"); // 写出换行 fw.write("\r\n"); // 写出字符串 fw.write("程序员"); // 关闭资源 fw.close(); } }
输出结果:
黑马
程序员
小贴士:字符流,只能操作文本文件,不能操作图片,视频等非文本文件。
当我们单纯读或者写文本文件时 使用字符流 其他情况使用字节流
4. IO异常的处理
JDK7前处理
之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理,建议使用try...catch...finally
代码块,处理异常部分,代码使用演示:
public class HandleException1 { public static void main(String[] args) { // 声明变量 FileWriter fw = null; try { //创建流对象 fw = new FileWriter("fw.txt"); // 写出数据 fw.write("黑马程序员"); //黑马程序员 } catch (IOException e) { e.printStackTrace(); } finally { try { if (fw != null) { fw.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
JDK7的处理(扩展知识点了解内容)
还可以使用JDK7优化后的try-with-resource
语句,该语句确保了每个资源在语句结束时关闭。所谓的资源(resource)是指在程序完成后,必须关闭的对象。
格式:
try (创建流对象语句,如果多个,使用';'隔开) { // 读写数据 } catch (IOException e) { e.printStackTrace(); }
代码使用演示:
public class HandleException2 { public static void main(String[] args) { // 创建流对象 try ( FileWriter fw = new FileWriter("fw.txt"); ) { // 写出数据 fw.write("黑马程序员"); //黑马程序员 } catch (IOException e) { e.printStackTrace(); } } }
JDK9的改进(扩展知识点了解内容)
JDK9中try-with-resource
的改进,对于引入对象的方式,支持的更加简洁。被引入的对象,同样可以自动关闭,无需手动close,我们来了解一下格式。
改进前格式:
// 被final修饰的对象 final Resource resource1 = new Resource("resource1"); // 普通对象 Resource resource2 = new Resource("resource2"); // 引入方式:创建新的变量保存 try (Resource r1 = resource1; Resource r2 = resource2) { // 使用对象 }
改进后格式:
// 被final修饰的对象 final Resource resource1 = new Resource("resource1"); // 普通对象 Resource resource2 = new Resource("resource2"); // 引入方式:直接引入 try (resource1; resource2) { // 使用对象 }
改进后,代码使用演示:
public class TryDemo { public static void main(String[] args) throws IOException { // 创建流对象 final FileReader fr = new FileReader("in.txt"); FileWriter fw = new FileWriter("out.txt"); // 引入到try中 try (fr; fw) { // 定义变量 int b; // 读取数据 while ((b = fr.read())!=-1) { // 写出数据 fw.write(b); } } catch (IOException e) { e.printStackTrace(); } } }
5. 综合练习
练习1:拷贝文件夹
public class Test01 { public static void main(String[] args) throws IOException { //拷贝一个文件夹,考虑子文件夹 //1.创建对象表示数据源 File src = new File("D:\\aaa\\src"); //2.创建对象表示目的地 File dest = new File("D:\\aaa\\dest"); //3.调用方法开始拷贝 copydir(src,dest); } /* * 作用:拷贝文件夹 * 参数一:数据源 * 参数二:目的地 * * */ private static void copydir(File src, File dest) throws IOException { dest.mkdirs(); //递归 //1.进入数据源 File[] files = src.listFiles(); //2.遍历数组 for (File file : files) { if(file.isFile()){ //3.判断文件,拷贝 FileInputStream fis = new FileInputStream(file); FileOutputStream fos = new FileOutputStream(new File(dest,file.getName())); byte[] bytes = new byte[1024]; int len; while((len = fis.read(bytes)) != -1){ fos.write(bytes,0,len); } fos.close(); fis.close(); }else { //4.判断文件夹,递归 copydir(file, new File(dest,file.getName())); } } } }
练习2:文件加密
public class Test02 { public static void main(String[] args) throws IOException { /* 为了保证文件的安全性,就需要对原始文件进行加密存储,再使用的时候再对其进行解密处理。 加密原理: 对原始文件中的每一个字节数据进行更改,然后将更改以后的数据存储到新的文件中。 解密原理: 读取加密之后的文件,按照加密的规则反向操作,变成原始文件。 ^ : 异或 两边相同:false 两边不同:true 0:false 1:true 100:1100100 10: 1010 1100100 ^ 0001010 __________ 1101110 ^ 0001010 __________ 1100100 */ } public static void encryptionAndReduction(File src, File dest) throws IOException { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(dest); int b; while ((b = fis.read()) != -1) { fos.write(b ^ 2); } //4.释放资源 fos.close(); fis.close(); } }
练习3:数字排序
文本文件中有以下的数据: 2-1-9-4-7-8 将文件中的数据进行排序,变成以下的数据: 1-2-4-7-8-9
实现方式一:
p
ublic class Test03 { public static void main(String[] args) throws IOException { /* 文本文件中有以下的数据: 2-1-9-4-7-8 将文件中的数据进行排序,变成以下的数据: 1-2-4-7-8-9 */ //1.读取数据 FileReader fr = new FileReader("myio\\a.txt"); StringBuilder sb = new StringBuilder(); int ch; while((ch = fr.read()) != -1){ sb.append((char)ch); } fr.close(); System.out.println(sb); //2.排序 String str = sb.toString(); String[] arrStr = str.split("-");//2-1-9-4-7-8 ArrayList<Integer> list = new ArrayList<>(); for (String s : arrStr) { int i = Integer.parseInt(s); list.add(i); } Collections.sort(list); System.out.println(list); //3.写出 FileWriter fw = new FileWriter("myio\\a.txt"); for (int i = 0; i < list.size(); i++) { if(i == list.size() - 1){ fw.write(list.get(i) + ""); }else{ fw.write(list.get(i) + "-"); } } fw.close(); } }
实现方式二:
public class Test04 { public static void main(String[] args) throws IOException { /* 文本文件中有以下的数据: 2-1-9-4-7-8 将文件中的数据进行排序,变成以下的数据: 1-2-4-7-8-9 细节1: 文件中的数据不要换行 细节2: bom头 */ //1.读取数据 FileReader fr = new FileReader("myio\\a.txt"); StringBuilder sb = new StringBuilder(); int ch; while((ch = fr.read()) != -1){ sb.append((char)ch); } fr.close(); System.out.println(sb); //2.排序 Integer[] arr = Arrays.stream(sb.toString() .split("-")) .map(Integer::parseInt) .sorted() .toArray(Integer[]::new); //3.写出 FileWriter fw = new FileWriter("myio\\a.txt"); String s = Arrays.toString(arr).replace(", ","-"); String result = s.substring(1, s.length() - 1); fw.write(result); fw.close(); } }