zoukankan      html  css  js  c++  java
  • JavaSE知识-21(IO(字符流)&字符流其他内容&递归)

    21.01_IO流(字符流FileReader)

    • 1.字符流是什么
      • 字符流是可以直接读写字符的IO流
      • 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出.
    • 2.FileReader
      • FileReader类的read()方法可以按照字符大小读取
    package com.hwh.chario;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    public class Demo1_FileReader {
    			/**
    			 * @param args
    			 * @throws IOException 
    			 */
    			public static void main(String[] args) throws IOException {
    				//demo1();
    				FileReader fr = new FileReader("xxx.txt");//xxx中为大家好
    				int c;
    				
    				while((c = fr.read()) != -1) {					//通过项目默认的码表一次读取一个字符
    					System.out.print((char)c);//大家好
    				}
    				
    				fr.close();
    			}
    
    			public static void demo1() throws FileNotFoundException, IOException {
    				FileReader fr = new FileReader("xxx.txt");
    				int x = fr.read();
    				System.out.println(x);//22823
    				char c = (char)x;
    				System.out.println(c);//大
    				fr.close();
    			}
    		}
    

    21.02_IO流(字符流FileWriter)

    • FileWriter类的write()方法可以自动把字符转为字节写出
    package com.hwh.chario;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Demo2_FileWriter {
    			/**
    			 * @param args
    			 * @throws IOException 
    			 */
    			public static void main(String[] args) throws IOException {
    				FileWriter fw = new FileWriter("yyy.txt");
    				fw.write("你好,很高兴认识你!");
    				fw.write(97);//a
    				fw.close();
    			}
    		}
    

    21.03_IO流(字符流的拷贝)

    package com.hwh.chario;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Demo3_Copy {
    			public static void main(String[] args) throws IOException {
    				FileReader fr = new FileReader("xxx.txt");
    				FileWriter fw = new FileWriter("zzz.txt");
    				
    				int c;
    				while((c = fr.read()) != -1) {
    					fw.write(c);
    				}
    				
    				fr.close();
    				fw.close();				//Writer类中有一个2k的小缓冲区,如果不关流,就会将内容写到缓冲区里,关流会将缓冲区内容刷新,再关闭
    			}
    }
    

    21.04_IO流(什么情况下使用字符流)

    • 字符流也可以拷贝文本文件, 但不推荐使用. 因为读取时会把字节转为字符, 写出时还要把字符转回字节.
    • 程序需要读取一段文本, 或者需要写出一段文本的时候可以使用字符流
    • 读取的时候是按照字符的大小读取的,不会出现半个中文
    • 写出的时候可以直接将字符串写出,不用转换为字节数组

    21.05_IO流(字符流是否可以拷贝非纯文本的文件)

    • 不可以拷贝非纯文本的文件
    • 因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去
    • 如果是?,直接写出,这样写出之后的文件就乱了,看不了了
    package com.heima.chario;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Demo3_Copy {
    	/**
    	 * @param args
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		//字符流不能拷贝非纯文本的文件
    		FileReader fr = new FileReader("双元.jpg");
    		FileWriter fw = new FileWriter("copy.jpg");
    		
    		int c;
    		while((c = fr.read()) != -1) {
    			fw.write(c);
    		}
    		
    		fr.close();
    		fw.close();
    	}
    }
    

    运行结果为
    打开新生成照片, Win照片查看器无法打开, 因为此文件可能已损坏损毁或过大

    21.06_IO流(自定义字符数组的拷贝)

    package com.hwh.chario;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Demo3_Copy {
    			/**
    			 * @param args
    			 * @throws IOException 
    			 */
    			public static void main(String[] args) throws IOException {
    				FileReader fr = new FileReader("xxx.txt");
    				FileWriter fw = new FileWriter("yyy.txt");
    				
    				char[] arr = new char[1024];
    				int len;
    				while((len = fr.read(arr)) != -1) {			//将文件上的数据读取到字符数组中
    					fw.write(arr,0,len);					//将字符数组中的数据写到文件上
    				}
    				
    				fr.close();
    				fw.close();
    			}
    		}
    

    21.07_IO流(带缓冲的字符流)

    • BufferedReader的read()方法读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序, 降低读取文件的次数, 提高效率
    • BufferedWriter的write()方法写出字符时会先写到缓冲区, 缓冲区写满时才会写到文件, 降低写文件的次数, 提高效率
    package com.heima.chario;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Demo3_Copy {
    	/**
    	 * @param args
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new FileReader("xxx.txt"));
    		BufferedWriter bw = new BufferedWriter(new FileWriter("yyy.txt"));
    		
    		int c;
    		while((c = br.read()) != -1) {
    			bw.write(c);
    		}
    		
    		br.close();
    		bw.close();
    	}
    }
    

    21.08_IO流(readLine()和newLine()方法)

    • BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)
    • BufferedWriter的newLine()可以输出一个跨平台的换行符号" "
    package com.hwh.chario;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Demo4_Buffered {
    	public static void main(String[] args) throws IOException {
    			/**
    			 * @param args
    			 * 带缓冲区的流中的特殊方法
    			 * readLine()
    			 * newLine();
    			 * 
    			 * newLine()与
    的区别
    			 * newLine()是跨平台的方法
    			 * 
    只支持的是windows系统
    			 * @throws IOException 
    			 */
    				//demo1();
    				BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
    				BufferedWriter bw = new BufferedWriter(new FileWriter("aaa.txt"));
    				
    				String line;
    				while((line = br.readLine()) != null) {
    					bw.write(line);
    					bw.newLine();							//写出回车换行符
    					//或者bw.write("
    ");
    				}
    				
    				br.close();
    				bw.close();
    			}
    
    			public static void demo1() throws FileNotFoundException, IOException {
    				BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
    				String line;
    				
    				while((line = br.readLine()) != null) {
    					System.out.println(line);
    				}
    				
    				br.close();
    			}
    		}
    

    21.09_IO流(将文本反转)

    • 将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
    package com.hwh.test;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    public class Test1 {
    		/**
    		 * 分析:
    		 * 1,创建输入输出流对象
    		 * 2,创建集合对象
    		 * 3,将读到的数据存储在集合中
    		 * 4,倒着遍历集合将数据写到文件上
    		 * 5,关流
    		 * @throws IOException 
    		 * 
    		 * 注意事项:
    		 * 流对象尽量晚开早关
    		 */
    		public static void main(String[] args) throws IOException {
    			//改写后是尽量晚开早关
    			// 1,创建输入输出流对象
    			BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
    			
    			//2,创建集合对象
    			ArrayList<String> list = new ArrayList<>();
    			//3,将读到的数据存储在集合中
    			String line;
    			while((line = br.readLine()) != null) {
    				list.add(line);
    			}
    			br.close();											//关流
    			
    			//4,倒着遍历集合将数据写到文件上
    			BufferedWriter bw = new BufferedWriter(new FileWriter("revzzz.txt"));
    			for(int i = list.size() - 1; i >= 0; i--) {
    				bw.write(list.get(i));
    				bw.newLine();
    			}
    			//5,关流
    			
    			bw.close();
    		}
    	}
    

    21.10_IO流(LineNumberReader)

    • LineNumberReader是BufferedReader的子类, 具有相同的功能, 并且可以统计行号
      • 调用getLineNumber()方法可以获取当前行号
      • 调用setLineNumber()方法可以设置当前行号
    package com.hwh.chario;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.LineNumberReader;
    public class Demo5_LineNumberReader {
    		/**
    		 * @param args
    		 * @throws IOException 
    		 */
    		public static void main(String[] args) throws IOException {
    			LineNumberReader lnr = new LineNumberReader(new FileReader("zzz.txt"));
    			
    			String line;
    			lnr.setLineNumber(100);//行号从101开始
    			while((line = lnr.readLine()) != null) {
    				System.out.println(lnr.getLineNumber() + ":" + line);
    			}
    			
    			lnr.close();
    		}
    
    	}
    

    21.11_IO流(装饰设计模式)

    package com.hwh.chario;
    public class Demo6_Wrap {
    	/**
    	 * @param args
    	 * 装饰设计模式的好处是:
    	 * 耦合性不强,被装饰的类的变化与装饰类的变化无关
    	 */
    	public static void main(String[] args) {
    		HMStudent hms = new HMStudent(new Student());
    		hms.code();
    	}
    }
    
    interface Coder {
    	public void code();
    }
    
    class Student implements Coder {
    	@Override
    	public void code() {
    		System.out.println("javase");
    		System.out.println("javaweb");
    	}
    	
    }
    
    class HMStudent implements Coder {
    	//1,获取被装饰类的引用
    	private Student s;						//获取学生引用
    	
    	//2,在构造方法中传入被装饰类的对象
    	public HMStudent(Student s) {
    		this.s = s;
    	}
    
    	//3,对原有的功能进行升级
    	@Override
    	public void code() {
    		s.code();
    		System.out.println("ssh");
    		System.out.println("数据库");
    		System.out.println("大数据");
    		System.out.println("...");
    	}
    }
    

    运行结果为
    javase
    javaweb
    ssh
    数据库
    大数据
    ...

    21.12_IO流(使用指定的码表读写字符)

    • FileReader是使用默认码表读取文件, 如果需要使用指定码表读取, 那么可以使用InputStreamReader(字节流,编码表)
    • FileWriter是使用默认码表写出文件, 如果需要使用指定码表写出, 那么可以使用OutputStreamWriter(字节流,编码表)

    package com.hwh.chario;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    public class Demo7_TransIO {
    		/**
    		 * @param args
    		 * @throws IOException 
    		 */
    		public static void main(String[] args) throws IOException {
    			//demo1();
    			//demo2();
    			BufferedReader br = 								//更高效的读
    					new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8"));
    			BufferedWriter bw = 								//更高效的写
    					new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"));
    			int c;
    			while((c = br.read()) != -1) {
    				bw.write(c);//成功将utf-8中文本"你好你好"写入gbk
    			}
    			
    			br.close();
    			bw.close();
    		}
    
    		public static void demo2() throws UnsupportedEncodingException,
    				FileNotFoundException, IOException {
    			InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"), "uTf-8");	//指定码表读字符
    			OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk");	//指定码表写字符
    			
    			int c;
    			while((c = isr.read()) != -1) {
    				osw.write(c);//成功将utf-8中文本"你好你好"写入gbk
    			}
    			
    			isr.close();
    			osw.close();
    		}
    
    		public static void demo1() throws FileNotFoundException, IOException {
    			//用默认编码表读写,出现乱码 //浣犲ソ浣犲ソ
    			FileReader fr = new FileReader("utf-8.txt");				
    			FileWriter fw = new FileWriter("gbk.txt");
    			
    			int c;
    			while((c = fr.read()) != -1) {
    				fw.write(c);
    			}
    			
    			fr.close();
    			fw.close();
    		}
    	}
    

    21.13_IO流(转换流图解)

    • 画图分析转换流

    21.14_IO流(获取文本上字符出现的次数)

    • 获取一个文本上每个字符出现的次数,将结果写在times.txt上
    package com.hwh.test;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.TreeMap;
    public class Test3 {
    		/**
    		 * 分析:
    		 * 1,创建带缓冲的输入流对象
    		 * 2,创建双列集合对象TreeMap
    		 * 3,将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,就将键和1存储,如果包含这个键,就将该键和值加1存储
    		 * 4,关闭输入流
    		 * 5,创建输出流对象
    		 * 6,遍历集合将集合中的内容写到times.txt中
    		 * 7,关闭输出流
    		 * @throws IOException 
    		 */
    		public static void main(String[] args) throws IOException {
    			//1,创建带缓冲的输入流对象
    			BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
    			//2,创建双列集合对象TreeMap
    			TreeMap<Character, Integer> tm = new TreeMap<>();
    			//3,将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,就将键和1存储,如果包含这个键,就将该键和值加1存储
    			int ch;
    			while((ch = br.read()) != -1) {
    				char c = (char)ch;					//强制类型转换
    				/*if(!tm.containsKey(c)) {
    					tm.put(c, 1);
    				}else {
    					tm.put(c, tm.get(c) + 1);
    				}*/
    				tm.put(c, !tm.containsKey(c) ? 1 : tm.get(c) + 1);
    			}
    			//4,关闭输入流
    			br.close();
    			//5,创建输出流对象
    			BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt"));
    			//6,遍历集合将集合中的内容写到times.txt中
    			for(Character key : tm.keySet()) {
    				switch (key) {
    				case '	':
    					bw.write("\t" + "=" + tm.get(key)); 	
    					break;
    				case '
    ':
    					bw.write("\n" + "=" + tm.get(key)); 
    					break;
    				case '
    ':
    					bw.write("\r" + "=" + tm.get(key)); 
    					break;
    				default:
    					bw.write(key + "=" + tm.get(key)); 			//写出键和值
    					break;
    				}
    				bw.newLine();
    			}
    			//7,关闭输出流
    			bw.close();
    		}
    	}
    

    运行结果为 =11 =11 =32 "=2 (=5 )=5.......

    21.15_IO流(试用版软件)

    • 当我们下载一个试用版软件,没有购买正版的时候,每执行一次就会提醒我们还有多少次使用机会用学过的IO流知识,模拟试用版软件,试用10次机会,执行一次就提示一次您还有几次机会,如果次数到了提示请购买正版
    package com.hwh.test;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    public class Test4 {
    		/**
    		 *  当我们下载一个试用版软件,没有购买正版的时候,每执行一次就会提醒我们还有多少次使用机会用学过的IO流知识,模拟试用版软件,
    		 *  试用10次机会,执行一次就提示一次您还有几次机会,如果次数到了提示请购买正版
    		 * @throws IOException 
    		 * 分析:
    		 * 1,创建带缓冲的输入流对象,因为要使用readLine方法,可以保证数据的原样性
    		 * 2,将读到的字符串转换为int数
    		 * 3,对int数进行判断,如果大于0,就将其--写回去,如果不大于0,就提示请购买正版
    		 * 4,在if判断中要将--的结果打印,并将结果通过输出流写到文件上
    		 */
    		public static void main(String[] args) throws IOException {
    			//1,创建带缓冲的输入流对象,因为要使用readLine方法,可以保证数据的原样性
    			BufferedReader br = new BufferedReader(new FileReader("config.txt"));
    			//2,将读到的字符串转换为int数
    			String line = br.readLine();
    			int times = Integer.parseInt(line);					//将数字字符串转换为数字
    			//3,对int数进行判断,如果大于0,就将其--写回去,如果不大于0,就提示请购买正版
    			if(times > 0) {
    				//4,在if判断中要将--的结果打印,并将结果通过输出流写到文件上
    				System.out.println("您还有" + times-- + "次机会");
    				FileWriter fw = new FileWriter("config.txt");
    				fw.write(times +"");
    				fw.close();
    			}else {
    				System.out.println("您的试用次数已到,请购买正版");
    			}
    			//关闭流
    			br.close();
    		}
    	}
    

    21.16_File类(递归)

    • 5的阶乘
    package com.hwh.chario;
    public class Demo8_Digui {
    		/**
    		 * @param args
    		 * 递归:方法自己调用自己
    		 * 5!
    		 * 5 * 4 * 3 * 2 * 1
    		 * 
    		 * 5 * fun(4)(代表4!)
    		 * 		4 * fun(3)(代表3!)
    		 * 				3 * fun(2)(代表2!) 
    		 * 						2 * fun(1)(代表1!)
    		 * 递归的弊端:不能调用次数过多,容易导致栈内存溢出
    		 * 递归的好处:不用知道循环次数
    		 * 
    		 * 构造方法是否可以递归调用?
    		 * 构造方法不能使用递归调用
    		 * 
    		 * 递归调用是否必须有返回值?
    		 * 不一定(可以有,也可以没有)
    		 */
    		public static void main(String[] args) {
    			/*int result = 1;
    			
    			for(int i = 1; i <= 5; i++) {
    				result = result * i;
    			}
    			
    			System.out.println(result);*/
    			System.out.println(fun(5));
    		}
    		
    		public static int fun(int num) {
    			if(num == 1) {
    				return 1;
    			}else {
    				return num * fun(num - 1);
    			}
    		}
    	}
    

    21.17_File类(练习)

    • 需求:从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名
    package com.hwh.test;
    
    import java.io.File;
    import java.util.Scanner;
    
    public class Test5 {
    		/**
    		 * 需求:从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名
    		 * 
    		 * 分析:
    		 * 从键盘接收一个文件夹路径
    		 * 1,如果录入的是不存在,给与提示
    		 * 2,如果录入的是文件路径,给与提示
    		 * 3,如果是文件夹路径,直接返回
    		 * 
    		 * 打印出该文件夹下所有的.java文件名
    		 * 1,获取到该文件夹路径下的所有的文件和文件夹,存储在File数组中
    		 * 2,遍历数组,对每一个文件或文件夹做判断
    		 * 3,如果是文件,并且后缀是.java的,就打印
    		 * 4,如果是文件夹,就递归调用
    		 */
    		public static void main(String[] args) {
    			File dir = getDir();
    			printJavaFile(dir);
    		}
    
    		/*
    		 * 获取键盘录入的文件夹路径
    		 * 1,返回值类型File
    		 * 2,不需要有参数
    		 */
    		public static File getDir() {
    			Scanner sc = new Scanner(System.in);				//创建键盘录入对象
    			System.out.println("请输入一个文件夹路径");
    			while(true) {
    				String line = sc.nextLine();					//将键盘录入的文件夹路径存储
    				File dir = new File(line);						//封装成File对象
    				if(!dir.exists()) {
    					System.out.println("您录入的文件夹路径不存在,请重新录入");
    				}else if(dir.isFile()) {
    					System.out.println("您录入的是文件路径,请重新录入文件夹路径");
    				}else {
    					return dir;
    				}
    			}
    		}
    		/*
    		 * 获取文件夹路径下的所.java文件
    		 * 1,返回值类型 void
    		 * 2,参数列表File dir
    		 */
    		public static void printJavaFile(File dir) {
    			//1,获取到该文件夹路径下的所有的文件和文件夹,存储在File数组中
    			File[] subFiles = dir.listFiles();
    			//2,遍历数组,对每一个文件或文件夹做判断
    			for (File subFile : subFiles) {
    				//3,如果是文件,并且后缀是.java的,就打印
    				if(subFile.isFile() && subFile.getName().endsWith(".java")) {
    					System.out.println(subFile);
    				//4,如果是文件夹,就递归调用
    				}else if (subFile.isDirectory()){
    					printJavaFile(subFile);
    				}
    			}
    		}
    	}
    
  • 相关阅读:
    【JAVA笔记——道】JAVA对象销毁
    【JAVA笔记——道】并发编程CAS算法
    httpClientUtil的get请求
    python基础 day11 下 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业
    python基础 day11 上 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 事务 索引 python 操作mysql ORM sqlachemy学习
    Python基础 Day10 Gevent协程 SelectPollEpoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 RedisMemcached缓存 Paramiko SSH Twsited网络框架
    python基础 day9 进程、与线程区别 python GIL全局解释器锁 线程 进程
    python基础 day8 Socket语法及相关 SocketServer实现多并发
    python基础 day7 面向对象高级语法部分 异常处理 异常处理 Socket开发基础
    python基础 day6 面向对象的特性:封装、继承、多态 类、方法、
  • 原文地址:https://www.cnblogs.com/albieh/p/12321220.html
Copyright © 2011-2022 走看看