JAVA基础再回首(二十二)——转换流概述及用法、简化写法FileWriter和 FileReader、字符缓冲流及特殊用法、字节流字符流复制文件方法总结

原创 2016年09月04日 23:47:21

JAVA基础再回首(二十二)——转换流概述及用法、简化写法FileWriter和 FileReader、字符缓冲流及特殊用法、字节流字符流复制文件方法总结

版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917

这篇我们继续IO流的学习。

转换流概述

  • OutputStreamWriter 字符输出流
    • public OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
    • public OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
  • InputStreamReader 字符输入流
    • public InputStreamReader(InputStream in):用默认的编码读取数据
    • public InputStreamReader(InputStream in,String charsetName):用指定的编码读取数据

这两个其实很好理解,只要我们保持读取数据和写入数据的编码格式一致就可以了。

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        // 创建对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "UTF-8"); // 指定UTF-8
        // 写数据
        osw.write("中国");

        // 释放资源
        osw.close();
    }
}
//上面我们写入数据的时候指定了UTF-8的编码格式,那么我们在读取数据的时候也要指定是UTF-8的编码格式,如果我们不指定采用默认的编码格式写入数据,那么在读取数据的时候我们也不用去指定了,代码也会采用默认的编码去读取。
//那么我们就来完成上面文件的读取代码
public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        // 创建对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"), "UTF-8");

        // 读取数据
        // 一次读取一个字符
        int ch = 0;
        while ((ch = isr.read()) != -1) {
            System.out.print((char) ch);
        }

        // 释放资源
        isr.close();
    }
}

下面我们来看OutputStreamWriter的方法

  • 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):写一个字符串的一部分

来练习一下吧

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        // 创建对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));

        // 写数据
        // public void write(int c):写一个字符
         osw.write('a');
         osw.write(97);

        // public void write(char[] cbuf):写一个字符数组
         char[] chs = {'a','b','c','d','e'};
         osw.write(chs);

        // public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
         osw.write(chs,1,3);

        // public void write(String str):写一个字符串
         osw.write("杭州G20峰会");

        // public void write(String str,int off,int len):写一个字符串的一部分
        osw.write("习近平出席", 0, 3);//这是的0,3意思是从下标为0的字符开始向后写3个

        // 刷新缓冲区
        osw.flush();
        osw.write("平致开幕词", 1, 3);

        // 释放资源
        osw.close();

    }
}

运行程序打开osw.txt,我们来看一下
这里写图片描述

我们在用转换流时,它用到了缓冲区,所以我们就需要刷新,调用flush()方法。
但是你细心点就会发现,在刷新缓冲区后还可以写入数据。如果当我们释放资源后就不可以写入数据了,那么这就引出一个问题

close()和flush()的区别?

  • close()关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
  • flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。

OutputStreamWriter他有写数据的方法,肯定有读数据的方法,我们来看一下

  • OutputStreamWriter读数据方法
    • public int read():一次读取一个字符
    • public int read(char[] cbuf):一次读取一个字符数组
public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        // 创建对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream(
                "StringDemo.java"));

        // 一次读取一个字符
         int ch = 0;
         while ((ch = isr.read()) != -1) {
             System.out.print((char) ch);
         }

        // 释放资源
        isr.close();
    }
}

上面是一次读取一个字符,当然我们也可以一次读取一个字符数组

    // 一次读取一个字符数组
        char[] chs = new char[1024];
        int len = 0;
        while ((len = isr.read(chs)) != -1) {
            System.out.print(new String(chs, 0, len));
        }

转换流的简化写法

转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类。

  • FileWriter
  • FileReader

所以呢,我们就可以得出一下总结

  • OutputStreamWriter = FileOutputStream + 编码表(GBK)
  • FileWriter = FileOutputStream + 编码表(GBK)
  • InputStreamReader = FileInputStream + 编码表(GBK)
  • FileReader = FileInputStream + 编码表(GBK)

那我们就用FileWriter和FileReader来复制一个文件的操作吧

public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        // 封装数据源
        FileReader fr = new FileReader("a.txt");
        // 封装目的地
        FileWriter fw = new FileWriter("b.txt");

        // 一次一个字符
        int ch = 0;
        while ((ch = fr.read()) != -1) {
            fw.write(ch);
        }

        // 释放资源
        fw.close();
        fr.close();
    }
}

或者我们一次读取一个字符数组。

        // 一次一个字符数组
        char[] chs = new char[1024];
        int len = 0;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
            fw.flush();
        }

很明显这种方法就简单方便了好多。

上篇我们学习了字节缓冲流,那么这篇我们学习的字符它肯定也是有缓冲流的,我们就来学习一下。

字符缓冲流

字符流为了高效读写,也提供了对应的字符缓冲流。

  • BufferedWriter:字符缓冲输出流

  • BufferedReader:字符缓冲输入流

我们先来学习BufferedWriter:字符缓冲输出流

  • 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
  • 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
public class BufferedWriterDemo {
    public static void main(String[] args) {
        try {
            // 创建一个字符写入流对象
            FileWriter fw = new FileWriter("bw.txt");
            // 为了提高写入流的效率加入了缓冲技术
            BufferedWriter bw = new BufferedWriter(fw);

            //写入数据
            bw.write("hello");
            //换行
            bw.newLine();
            bw.write("world");
            bw.newLine();
            bw.write("java");
            //只要用到了缓冲区,就需要刷新
            bw.flush();
            //释放资源
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行程序在bw.txt文件中可以看到这样的结果
这里写图片描述

下面我们来学习BufferedReader:字符缓冲输入流

  • 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
  • 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
public class BufferedReaderDemo {
    public static void main(String[] args) {
        try {
            // 创建字符缓冲输入流对象
            BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
            // 一次读取一个字符
            int ch = 0;
            while ((ch = br.read()) != -1) {
                System.out.print((char) ch);
            }

            // 释放资源
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

当然我们也可以一次读取一个字符数组


            // 一次读取一个字符数组
            char[] chs = new char[1024];
            int len = 0;
            while ((len = br.read(chs)) != -1) {
                System.out.print(new String(chs, 0, len));
            }

字符缓冲流的特殊用法

我们在上面讲字符缓冲流输出数据的时候,代码中用到了**换行**newLine()
那么我们下面就来讲一下字符缓冲流的特殊用法

  • BufferedWriter:
    • public void newLine():根据系统来决定换行符
  • BufferedReader:
    • public String readLine():一次读取一行数据

根据系统来决定换行符,这个用法很简单,就不做演示了,我们来看下 BufferedReader的readLine()方法

readLine( ):包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

public class BufferedDemo {
    public static void main(String[] args)  {

        try {
            // 创建字符缓冲输入流对象
            BufferedReader br = new BufferedReader(new FileReader("bw.txt"));

            // 一次读取一行数据
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

            //释放资源
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

练习:字符缓冲流特殊功能复制文本文件

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"));

        // 读写数据
        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        // 释放资源
        bw.close();
        br.close();
    }
}

我们要切记readLine()和newLine()是BufferedReader和BufferedWriter 的特殊功能。

好了,我们关于字符流就学这么多了,我们来总结一下,上篇学的字节流和这篇学的字符流

字节流复制数据4种方式和字符流复制数据5种方式学习


  • 字节流复制数据
    • 4种方式
  • 字符流复制数据
    • 5种方式

注意:我们除了用windows记事本能读懂的数据用字符流以外,其余的全部使用字节流。
下面我们就来给大家写一个例子总结一下

先总结字符流复制数据的 5种方式推荐掌握第5种。

//我们将c盘根目录下的a.txt文件复制到d盘根目录下并命名为b.txt
public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        String srcString = "c:\\a.txt";
        String destString = "d:\\b.txt";
        method1(srcString, destString);//第一种--基本字符流一次读写一个字符
        method2(srcString, destString);//第二种--基本字符流一次读写一个字符数组
        method3(srcString, destString);//第三种--字符缓冲流一次读写一个字符
        method4(srcString, destString);//第四种--字符缓冲流一次读写一个字符数组
        method5(srcString, destString);//第五种-- 字符缓冲流一次读写一个字符串
    }

    // 第五种字符缓冲流一次读写一个字符串
    private static void method5(String srcString, String destString)
            throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(srcString));
        BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        bw.close();
        br.close();
    }

    // 第四种字符缓冲流一次读写一个字符数组
    private static void method4(String srcString, String destString)
            throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(srcString));
        BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

        char[] chs = new char[1024];
        int len = 0;
        while ((len = br.read(chs)) != -1) {
            bw.write(chs, 0, len);
        }

        bw.close();
        br.close();
    }

    // 第三种字符缓冲流一次读写一个字符
    private static void method3(String srcString, String destString)
            throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(srcString));
        BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

        int ch = 0;
        while ((ch = br.read()) != -1) {
            bw.write(ch);
        }

        bw.close();
        br.close();
    }

    // 第二种基本字符流一次读写一个字符数组
    private static void method2(String srcString, String destString)
            throws IOException {
        FileReader fr = new FileReader(srcString);
        FileWriter fw = new FileWriter(destString);

        char[] chs = new char[1024];
        int len = 0;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
        }

        fw.close();
        fr.close();
    }

    // 第一种基本字符流一次读写一个字符
    private static void method1(String srcString, String destString)
            throws IOException {
        FileReader fr = new FileReader(srcString);
        FileWriter fw = new FileWriter(destString);

        int ch = 0;
        while ((ch = fr.read()) != -1) {
            fw.write(ch);
        }

        fw.close();
        fr.close();
    }
}

继续总结一下字节流复制数据的4种方式
我们知道用记事本打开并能够读懂,就用字符流,否则用字节流。
所以我们就来复制图片我们有4种方式。推荐掌握第4种。

public class CopyImageDemo {
    public static void main(String[] args) throws IOException {
        // 使用File对象做为参数
        File srcFile = new File("c:\\a.jpg");
        File destFile = new File("d:\\b.jpg");

        method1(srcFile, destFile);//第一种--基本字节流一次读写一个字节数组
        method2(srcFile, destFile);//第二种--基本字节流一次读写一个字节数组
        method3(srcFile, destFile);//第三种--字节缓冲流一次读写一个字节
        method4(srcFile, destFile);// 第四种--字节缓冲流一次读写一个字节数组
    }

    // 第四种字节缓冲流一次读写一个字节数组
    private static void method4(File srcFile, File destFile) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(destFile));

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
        }

        bos.close();
        bis.close();
    }

    // 第三种字节缓冲流一次读写一个字节
    private static void method3(File srcFile, File destFile) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(destFile));

        int by = 0;
        while ((by = bis.read()) != -1) {
            bos.write(by);
        }

        bos.close();
        bis.close();
    }

    // 第二种基本字节流一次读写一个字节数组
    private static void method2(File srcFile, File destFile) throws IOException {
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = fis.read(bys)) != -1) {
            fos.write(bys, 0, len);
        }

        fos.close();
        fis.close();
    }

    // 第一种基本字节流一次读写一个字节
    private static void method1(File srcFile, File destFile) throws IOException {
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        int by = 0;
        while ((by = fis.read()) != -1) {
            fos.write(by);
        }

        fos.close();
        fis.close();
    }
}

好了,我们关于字符流的学习就到这里,关于后面的总结大家可以多做练习就很清楚了。

欢迎有兴趣的同学加我朋友的QQ群:点击直接加群555974449 请备注:java基础再回首我们一起来玩吧。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用FileWriter 和FileReader实现文本文件的复制

通过选择合适的下列流进行文件的复制     a)字符流(FileWriter FileReader)     b)字节流(FileInputStream,FileOutputStream)   ...
  • miachen520
  • miachen520
  • 2016年06月16日 19:23
  • 334

IO流(File类,IO流的分类,字节流和字符流,转换流,缓冲流,对象序列化)

1.File类 File类可以在程序中 操作文件和目录。File类是通过建立File类对象,在调用File类的对象来进行相关操作的。 示例: public class Demo01 { publ...
  • dajiahuooo
  • dajiahuooo
  • 2015年07月23日 04:15
  • 1220

Java_io体系之FileWriter、FileReader简介、走进源码及示例——18

FileWriter、FileReader的使用、源码介绍、以及通过实例来说明为什么有时候使用文件字符流来操作文件时会造成文件损坏不能正常打开。...
  • chenghuaying
  • chenghuaying
  • 2013年12月10日 10:59
  • 1735

Java IO之处理流(缓冲流、转换流)

一、处理流:增强功能,提供性能,在节点流之上。二、节点流与处理流的关系节点流(字节流、字符流)处于IO操作的第一线,所有操作必须通过它们进行; 处理流可以对其他流进行处理(提高效率或操作灵活性)。三...
  • scgaliguodong123_
  • scgaliguodong123_
  • 2015年05月23日 18:57
  • 2066

IO流学习笔记(一)之FileWriter与FileReader

IO流IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中 流按照操作数据分为两种:字节流和字符流 流按流向分为:输入流和输出流输入流和输...
  • Megustas_JJC
  • Megustas_JJC
  • 2017年06月03日 16:56
  • 263

IO_缓冲流_转换流_字节转为字符_乱码分析_编码与解码JAVA152-154

IO_缓冲流_转换流_字节转为字符_乱码分析_编码与解码JAVA152-154
  • u013292493
  • u013292493
  • 2016年01月02日 13:49
  • 1166

java中的FileReader 与 BufferedReader类-读入本地文件形成字符串

来源:JDK API 1.6中文版 是什么? 类。 --------------- 能做什么? 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 ---------...
  • fengfeng043
  • fengfeng043
  • 2015年04月14日 23:49
  • 3154

字符流FileReader和Filewriter对文件的复制

复制文本文件图解 步骤: 1、创建FileReader对象与源文件连接,创建FileWriter对象与目标文件连接(FileReader fr=new FileReader(”demo.t...
  • luozhisheng
  • luozhisheng
  • 2018年01月07日 14:08
  • 28

Java IO中转换流的作用

字符流与字节流转换 InputStreamReader OutputStreamWriter 转换流的两个作用 提高对文本操作的便捷程度 操作文本涉及到指定编码...
  • u013905744
  • u013905744
  • 2016年07月16日 14:22
  • 5404

Java文件与io——复制文件和转换流

字节流与字符流的区别 在所有的流操作里,字节永远是最基础的。任何基于字节的操作都是正确的。无论是文本文件还是二进制的文件。 如果确认流里面只有可打印的字符,包括英文的和各种国家的文字,也包括中文,...
  • sunnylinner
  • sunnylinner
  • 2016年08月02日 09:46
  • 1574
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA基础再回首(二十二)——转换流概述及用法、简化写法FileWriter和 FileReader、字符缓冲流及特殊用法、字节流字符流复制文件方法总结
举报原因:
原因补充:

(最多只允许输入30个字)