Java学习之路(十二):IO流<二>

时间:2023-03-08 17:58:50

字符流

  • 字符流是可以直接读写字符的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());
}
}
}