day21 Java学习(IO(字符流))
IO流(字符流FileReader)
字符流:
* 字符流是可以直接读写字符的IO流。
* 字符流读取字符,就要先读取到字节数据,然后转为字符,如果要写出字符,需要把字符转为字节再写出。
什么情况下使用字符流:
* 字符流也可以拷贝文件,但不推荐使用,因为读取时会把字节转为字符,写出时还要把字符转回字节。
* 程序需要读一段文本,或者需要写出一段文本的时候可以使用字符流
* 读取的时候是按照字符的大小读取的,不会出现半个中文。
* 写出的时候可以直接将字符串写出,不用转为字节数组。
注意事项:
* 不可以拷贝非纯文本的文件。(文件会乱码)
IO流(字符流FileWriter)
* FileWriter类的write()方法可以自动把字符转为字节写出。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { // TODO 自动生成的方法存根 FileWriter fw=new FileWriter("eee.txt"); //创建文件 fw.write("六一快乐"); //write():把字符转为字节. fw.close(); //释放资源 }
IO流(字符流拷贝)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { FileReader fr = new FileReader("test.txt"); FileWriter fw = new FileWriter("eeecc.txt"); int b; while ((b = fr.read()) != -1) { fw.write(b); } fr.close(); fw.close(); //必须关闭,如果不关流,就会将内容写到缓冲区,关流会将缓冲区内容刷新,再关闭。 }
IO流(自定义字符数组拷贝)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { FileReader list = new FileReader("test.txt"); FileWriter list2 = new FileWriter("copy.txt"); char[] arr = new char[1024]; int len; while ((len = list.read(arr)) != -1) { list2.write(arr, 0, len); } list.close(); list2.close(); }
IO流(readLine( )和newLine( )方法)
* BufferedReader的readLine( )方法可以读取一行字符(不包含换行符号)。
* BufferedWriter的newLine( )可以输出一个跨平台的换行符号 “\r\b"。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { /* * newLine()和\r\n的区别: * newLine()是跨平台的方法。 * \r\n只支持windows系统。 */ BufferedReader br=new BufferedReader(new FileReader("ccc.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("aa.txt")); String line; while ((line=br.readLine())!=null) { bw.write(line); bw.newLine(); //写出回车换行符 (效果跟\r\n是一样的) } br.close(); bw.close(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { //需求:将文本反转 //注意事项:流对象尽量晚开早关 //1.创建输入输出流对象 BufferedReader br=new BufferedReader(new FileReader("ccc.txt")); //2.创建集合对象 List<String> list =new ArrayList<>(); String line; //3.将数据传到集合中 while ((line=br.readLine())!=null) { list.add(line); } //4.关流 br.close(); //5.倒着遍历集合将数据写到文件上 BufferedWriter bw=new BufferedWriter(new FileWriter("aass.txt")); for(int i=list.size()-1;i>=0;i--) { bw.write(list.get(i)); bw.newLine(); } bw.close(); }
IO流(装饰设计模式)
* 装饰设计模式的好处是:
* 耦合性不强,被装饰的类的变化与装饰类的变化无关。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) { // heima dd=new heima(new Student()); dd.code(); } } interface Coder { public void code(); } class Student implements Coder { @Override public void code() { System.out.println("javas"); System.out.println("javasd"); } } //装饰设计模式 class heima implements Coder{ //1.获取被装饰类的引用 private Student s; //获取学生引用 //2.在构造方法中传入被装饰类的引用 public heima(Student s) { this.s=s; } // 3.对原有的功能进行升级 @Override public void code() { // TODO 自动生成的方法存根 s.code(); System.out.println("大数据"); System.out.println("..."); }
IO流(使用指定的码表读写字符)
* FileReader 是使用默认码表读取文件,如果需要使用指定码表读取,那么可以使用InputStreamReader(字节流,编码表)
* FileWriter 是使用默认码表读取文件,如果需要使用指定码表写出,那么可以使用OutputStreamReader(字节流,编码表)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ccc.txt"), "UTF-8")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("aa.txt"), "GBK")); int ch; while ((ch = br.read()) != -1) { bw.write(ch); } br.close(); bw.close(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { // 创建带缓冲的流对象 BufferedReader br = new BufferedReader(new FileReader("aass.txt")); // 创建双列集合 TreeMap<Character, Integer> list = new TreeMap<>(); // 读到的字符存储在双列集合中 int line; while ((line = br.read()) != -1) { char info = (char) line; if (!list.containsKey(info)) { list.put(info, 1); } else { list.put(info, list.get(info) + 1); } } //关闭输入流 br.close(); // 创建输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("kkk.txt")); //6.遍历集合将集合中的内容写入到kkk.txt中 for (Character key : list.keySet()) { switch (key) { case '\t': bw.write("\\t" + "=" + list.get(key)); break; case '\n': bw.write("\\n" + "=" + list.get(key)); break; case '\r': bw.write("\\r" + "=" + list.get(key)); break; default: bw.write(key + "=" + list.get(key)); //写出键和值 break; } bw.newLine(); } bw.close(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) throws IOException { // 创建带缓冲区的输入流对象,使用readLine()可保证数据的原样性。 BufferedReader br = new BufferedReader(new FileReader("aa.txt")); String line = br.readLine(); // 将读到的字符串转换成int数 int num = Integer.parseInt(line); // 对其进行判断,>0就将其--写回去。 if (num > 0) { System.out.println("你还有" + num-- + "次机会"); FileWriter fw = new FileWriter("aa.txt"); fw.write(num + ""); fw.close(); } else { System.out.println("没次数了"); } // 关流 br.close(); }
File类(递归)
* 递归 :方法自己调用自己。
* 递归的弊端:不能调用过多,容易导致栈内存溢出。
* 递归的好处:不用指定循环次数。
* 构造方法不能使用递归调用。
* 递归调用返回值:不一定(可以有,也可以没有)
* FileReader 是使用默认码表读取文件,如果需要使用指定码表读取,那么可以使用InputStreamReader(字节流,编码表)