Java学习之路(十二):IO流<二>
字符流
- 字符流是可以直接读写字符的IO流
- 使用字符流从文件中读取字符的时候,需要先读取到字节数据,让后在转换为字符
- 使用字符流向文件中写入字符时,需要把字符转为字节在写入文件
Reader和Writer,这两个类是抽象类,一般我们使用的都是他们的子类
FileReader和FileWriter我们一般使用的
FileReader的使用:
- FileReader用于读取字符,调用read方法的时候,是读取一个字符
- read方法的放回值是int,它是把char转成了int
- 以后我们在读取纯文本的文件的时候,使用FileReader这个类,这样的话我们就不许要考虑乱码的问题
一个小小的例子:
package null08051400; import java.io.FileReader; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileReader fileReader = new FileReader("D:\\nullnull\\workspace2\\day03\\src\\null08051400\\new1.txt"); int i; while((i=fileReader.read())!=-1){ System.out.println((char)i); } fileReader.close(); } }
FileWriter的使用
和之前的IO流中的write都是一样的,这里我们直接列出一个例子:
package null08051408; import java.io.FileWriter; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub FileWriter writer = new FileWriter("D:\\nullnull\\workspace2\\day03\\src\\null08051408\\1.txt"); writer.write("你好"); writer.write("\r\n"); writer.write("你好"); writer.write("\r\n"); writer.close(); } }
字符流的拷贝
package null08051414; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws IOException { try( FileReader fileReader = new FileReader("D:\\nullnull\\workspace2\\day03\\src\\null08051400\\new1.txt"); FileWriter fileWriter = new FileWriter("D:\\nullnull\\workspace2\\day03\\src\\null08051414\\1.txt"); ){ int i; while((i=fileReader.read())!=-1){ fileWriter.write(i); } } } }
package null08051419; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws IOException { try( FileReader fileReader = new FileReader(""); FileWriter fileWriter = new FileWriter(""); ){ char[] ch = new char[8*1024]; int len; while((len=fileReader.read(ch))!=-1){ fileWriter.write(ch, 0, len); } } } }
使用字符流的场景
- 如果是读取文本文件,使用FileReader,不用考虑乱码的问题
- 如果是写入文本文件,不建议使用FileWriter,直接使用FileOutputStream好一些。因为是字节直接写入文件,不需要过多的数据类型的转换
使用FileReader读取字符:先读字节,把字节转成字符(byte===>char)
使用FileWriter写入字符:str转为字符数组,然后是字符转为字节写入文件
带缓冲的字符流
BufferedReader和BufferedWriter
在两个类的内部有一个缓冲区(字符数组)
read方法会读取8*1024个字符
write方法会写入8*1024个字符
package null08051558; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws IOException { FileReader fr = new FileReader(""); FileWriter fw = new FileWriter(""); BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw); int i; while((i=br.read())!=-1){ bw.write(i); } } }
BufferedReader的新方法readLIne()
BufferedWriter的新方法newLine()
package null08051603; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws IOException { FileReader fr = new FileReader(""); FileWriter fw = new FileWriter(""); BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw); String line = null; while((line=br.readLine())!=null){ bw.write(line); bw.newLine();//换行用 } } }
案例:将文本翻转写入留一个文件
package null08051607; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Demo01 { public static void main(String[] args) throws IOException { //创建一个集合对象,用于存储取出的内容 List<String> list = new ArrayList<String>(); //读取文件写入集合 BufferedReader br = new BufferedReader(new FileReader("")); String line = null; while((line=br.readLine())!=null){ list.add(line); } //倒叙循环集合,然后输入 BufferedWriter bw = new BufferedWriter(new FileWriter("")); for(int i=list.size()-1;i>=0;i--){ bw.write(i); bw.newLine(); } br.close(); bw.close(); } }
案例:获取文本中字符出现的次数
package null08051614; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; //获取一个文本中字符出现的次数 public class Demo01 { public static void main(String[] args) throws IOException { Map<Character,Integer> map = new HashMap<Character,Integer>(); FileReader fileReader = new FileReader(""); int i; while((i=fileReader.read())!=-1){ char ch = (char)i; if(map.get(ch)==null){ map.put(ch, 1); }else{ map.put(ch,map.get(ch)+1); } } fileReader.close(); System.out.println(map); } }
编码字符流
InputStreamReader:这个类主要用于指定编码的读字符
OutputStreamWriter:这个类主要用于指定编码的写入文件
一个小小的例子:
package null08051624; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class Demo01 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream(""); FileOutputStream fos = new FileOutputStream(""); InputStreamReader isr = new InputStreamReader(fis,"utf-8"); OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8"); BufferedReader br = new BufferedReader(isr); BufferedWriter bw = new BufferedWriter(osw); String line; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); } bw.close(); br.close(); } }
SequenceInputStream序列流
一个小小的例子:使用序列流将多个文件写入到同一个文件中
package null08051633; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.SequenceInputStream; //将两个文件的内容写到同一个文件中 public class Demo01 { public static void main(String[] args) throws IOException { //创建输入流 FileInputStream fis1 = new FileInputStream(""); FileInputStream fis2 = new FileInputStream(""); SequenceInputStream sis = new SequenceInputStream(fis1,fis2); //创建输出流 FileOutputStream fos = new FileOutputStream(""); int i; while((i=sis.read())!=-1){ fos.write(i); } sis.close(); fis2.close(); fos.close(); } }
package null08051639; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.Enumeration; import java.util.Vector; //多个文件输入到同一个文件 public class Demo01 { public static void main(String[] args) throws IOException { Vector<InputStream> vector = new Vector<InputStream>(); vector.add(new FileInputStream("")); vector.add(new FileInputStream("")); vector.add(new FileInputStream("")); Enumeration<InputStream> e = vector.elements(); SequenceInputStream sis = new SequenceInputStream(e); FileOutputStream fos = new FileOutputStream(""); int i; while((i = sis.read())!=-1){ fos.write(i); } fos.close(); sis.close(); } }
补充:递归
- 就是指在方法的内部调用自己
- 弊端:不能调用的次数过多,容易导致栈内存溢出
- 好处:可以执行不知道循环次数的循环
- 构造方法是不能递归的
- 递归方法可以有返回值
一个小小的例子:求5的阶乘
package null08051649; public class Demo01 { public static void main(String[] args) { int result = s(3); System.out.println(result); } public static int s(int i){ if(i==1){ return 1; }else{ return i*s(i-1); } } }
一个小小的例子:递归打印一个目录下的所有文件
public static void s(File dir){ File[] currentFileList = dir.listFiles(); for(File item:currentFileList){ if(item.isDirectory()){ s(item); }else{ System.out.println(item.getAbsolutePath()); } } }