【Java基础知识】IO类--字符流读写数据以及复制文件的几种方式

1、转换流OutputStreamWriter与InputStreamReader

Java中的字符是Unicode编码,是双字节的,InputStream与OutputStream是用来处理字节的,在处理字符文本时需要额外的程序代码。Java为字符文本的输入输出专门提供一套单独的类,Reader、Writer两个抽象类与InputStream、OutputStream两个类相同。可以在处理字符串时简化了我们的编程。
OutputStreamWriter与InputStreamReader这两个类把字节流转换成字符流,中间做了数据的转换,类似适配器模式的思想。

1.1 OutputStreamWriter

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
构造方法:

OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流。
OutputStreamWriter(OutputStream out,String charsetName):
根据指定编码把字节流数据转换为字符流。把字节流转换为字符流,字符流 = 字节流 + 编码表。

使用示例:向文本文件写入字符文本

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //IO.txt文件的格式为UTF-8
        OutputStreamWriter osw = new OutputStreamWriter(new 
                FileOutputStream("IO.txt"), "UTF-8");
        osw.write("中国");
        osw.close();
    }
}
OutputStreamWriter的方法:
    public void write(int c):写一个字符
    public void write(char[] cbuf):写一个字符数组
    public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
    public void write(String str):写一个字符串
    public void write(String str,int off,int len):写一个字符串的一部分

close()和flush()的区别?
A:close()在关闭流对象之前,先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("IO.txt"));            
        osw.write("我爱北京天安们", 2, 3);
        osw.flush();
        osw.close();
    }
}

1.2 InputStreamReader

InputStreamReader:是字节流通向字符流的桥梁,它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
构造方法:

InputStreamReader(InputStream is):用默认的编码读取数据
InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据

使用示例:从文本文件读取字符文本

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        //IO.txt文件的格式为UTF-8 
        InputStreamReader isr = new InputStreamReader(new 
                FileInputStream("IO.txt"), "UTF-8");    
        //一次读取一个字符
        int ch = 0;
        while ((ch = isr.read()) != -1) {
            System.out.print((char) ch);
        }
        isr.close();
    }
}

InputStreamReader的方法
int read():一次读取一个字符
int read(char[] chs):一次读取一个字符数组

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("IO.txt"));
        // 一次读取一个字符数组
        char[] chs = new char[1024];
        int len = 0;
        while ((len = isr.read(chs)) != -1) {
            System.out.print(new String(chs, 0, len));
        }
        isr.close();
    }
}

1.3 通过字符流进行文件复制

需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        OutputStreamWriter osw = new OutputStreamWriter(new 
                    FileOutputStream("b.txt"));         
        char[] chs = new char[1024];
        int len = 0;
        while ((len = isr.read(chs)) != -1) {
            osw.write(chs, 0, len);
        }
        osw.close();
        isr.close();
    }
}

2 FileReader与FileWriter

2.1 FileReader与FileWriter源码分析

继承InputStreamReader与OutputStreamWriter类
【FileReader源码】

public class FileReader extends InputStreamReader {
    public FileReader(String fileName) throws FileNotFoundException {
        super(new FileInputStream(fileName));
    }
    public FileReader(File file) throws FileNotFoundException {
        super(new FileInputStream(file));
    }
    public FileReader(FileDescriptor fd) {
        super(new FileInputStream(fd));
    }
}

【FileWriter源码】

public class FileWriter extends OutputStreamWriter {
    public FileWriter(String fileName) throws IOException {
        super(new FileOutputStream(fileName));
    }
    public FileWriter(String fileName, boolean append) throws IOException {
        super(new FileOutputStream(fileName, append));
    }
    public FileWriter(File file) throws IOException {
        super(new FileOutputStream(file));
    }
    public FileWriter(File file, boolean append) throws IOException {
        super(new FileOutputStream(file, append));
    }
    public FileWriter(FileDescriptor fd) {
        super(new FileOutputStream(fd));
    }
}

2.2 使用FileReader与FileWriter进行文本复制

由于我们常见的操作都是使用本地默认编码,所以,不用指定编码。而转换流的名称有点长,所以,Java就提供了其子类供我们使用。
OutputStreamWriter = FileOutputStream + 编码表(GBK)
FileWriter = FileOutputStream + 编码表(GBK)

InputStreamReader = FileInputStream + 编码表(GBK)
FileReader = FileInputStream + 编码表(GBK)

public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("a.txt");
        FileWriter fw = new FileWriter("b.txt");
        char[] chs = new char[1024];
        int len = 0;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
            fw.flush();
        }
        fw.close();
        fr.close();
    }
}

3、字符缓冲流BufferedReader与BufferedWriter

字符流为了高效读写,也提供了对应的字符缓冲流
BufferedWriter:字符缓冲输出流
BufferedReader:字符缓冲输入流

3.1 BufferedWriter

构造函数:
BufferedWriter(Writer out)
BufferedWriter(Writer out, int sz)
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小。
使用案例:

public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("IO.txt"));
        bw.write("hello");
        bw.write("world");
        bw.flush();
        bw.close();
    }
}

3.2 BufferedReader

构造函数:
BufferedReader(Reader in)
BufferedReader(Reader in, int sz)
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 可以指定缓冲区的大小,或者可使用默认的大小。
使用案例:

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("IO.txt"));
        char[] chs = new char[1024];
        int len = 0;
        while ((len = br.read(chs)) != -1) {
            System.out.print(new String(chs, 0, len));
        }
        br.close();
    }
}

3.3字符缓冲流特有的方法newLine( )和readLine( )

字符缓冲流的特殊方法:
BufferedWriter:public void newLine():
根据系统来决定换行符,行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 (‘\n’) 符。
BufferedReader:public String readLine():
使用案例:

public class BufferedDemo {
    public static void main(String[] args) throws IOException {
        write();
        read();
    }
    private static void read() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("IO.txt"));
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
    private static void write() throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("IO.txt"));
        for (int x = 0; x < 3; x++) {
            bw.write("hello" + x);
            // bw.write("\r\n");
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }
}
/*IO.txt的文本内容
    hello0
    hello1
    hello2
*/

4 文本复制的方法

文本复制方法一:逐个字符读取

public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
        char[] chs = new char[1024];
        int len = 0;
        while ((len = br.read(chs)) != -1) {
            bw.write(chs, 0, len);
            bw.flush();
        }
        bw.close();
        br.close();
    }
}

文本复制方法二:逐行文本读取

public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        bw.close();
        br.close();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值