前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java总结IO篇之字节流与字符流转化

Java总结IO篇之字节流与字符流转化

作者头像
张风捷特烈
发布2018-10-11 16:43:04
1.5K0
发布2018-10-11 16:43:04
举报
文章被收录于专栏:Android知识点总结

本篇接上篇:Java中的字符流,流的读写的细节参考上篇 本篇讲述字节流相关话题,包括字节流的读取与写出,字节流转化为字符流 1.明确是否是纯文本:纯文本 ? 字符流: 字节流 2.明确数据来源( 输入流 I )和数据流向( 输出流 O ) 3.I流和O流对接,数据传输 另外:需要字符编码转换,使用字节流转换字符流

代码语言:javascript
复制
数据来源( 输入流 I ):内存、磁盘、网络、键盘    
数据流向( 输出流 O ): 内存、磁盘、网络、控制台    
1.最常见的几种流

最常见的几种流.png

2.流与流之间的相互作用:转换与包装

转换流和包装流.png


一、FileOutputStream与FileInputStream
1.FileOutputStream:输出流,写出操作
代码语言:javascript
复制
 FileOutputStream fos = null;
 try {
     String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileInputStream.txt";
     fos = new FileOutputStream(fileName);
     fos.write("Line1 第一行".getBytes());//不需要刷新缓冲
 } catch (IOException e) {
     e.printStackTrace();
 } finally {
     try {
         if (fos != null) {
             fos.close();
         }
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

字节输出流.png


2.FileInputStream:输入流,读进操作
代码语言:javascript
复制
public static void main(String[] args) {
    try {
        String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileInputStream.txt";
        FileInputStream fis = new FileInputStream(fileName);
        //readOneByOne(fis);
        //readByByteArrayByWhile(fis);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
1)一个一个字节
代码语言:javascript
复制
private static void readOneByOne(FileInputStream fis) throws IOException {
    int ch = 0;
    while ((ch = fis.read()) != -1) {
        System.out.println(ch + "=" + (char) ch);
    }
}

一共输出了15个字节,和Line1 第一行有出入,原因: 在utf-8编码下,一个中文字符占三个字节

代码语言:javascript
复制
76=L  105=i  110=n  101=e  49=1  32=   231=ç  172=¬  172=¬  228=ä  184=¸  128=�  232=è  161=¡  140=�  
2)字节数组方式:
代码语言:javascript
复制
private static void readByByteArrayByWhile(FileInputStream fis) throws IOException {
    //字符数组循环读取
    byte[] buf = new byte[8];
    int len = 0;
    while ((len = fis.read(buf)) != -1) {
        System.out.println(new String(buf, 0, len));
    }
}

可见buf一次装个字节,由三个字节表示,被分成了两半,所以读出了乱码

代码语言:javascript
复制
//Line1 �
//�一行
代码语言:javascript
复制
文件字节数
System.out.println(fis.available());//15

二、使用字节流拷贝

视频大小:576M

1.使用FileInputStream和FileInputStream拷贝

耗时:6.162444569秒

代码语言:javascript
复制
private static void copy() {
    FileOutputStream fos = null;
    FileInputStream fis = null;
    try {
        fis = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\video.avi");
        fos = new FileOutputStream("F:\\javaTest\\IO\\video.avi");
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2.使用包装类BufferedOutputStream和BufferedInputStream拷贝:

方法耗时:33.478968503秒

代码语言:javascript
复制
private static void copyByBuf() {
    BufferedOutputStream bfos = null;
    BufferedInputStream bfis = null;
    try {
        FileInputStream fis = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\video.avi");
        bfis = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream("F:\\javaTest\\IO\\video.avi");
        bfos = new BufferedOutputStream(fos);
        int b = 0;
        while ((b = bfis.read()) != -1) {
            bfos.write(b);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (bfis != null) {
                bfis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (bfos != null) {
                bfos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、字节流转化为字符流
场景一:将键盘录入写入到本地磁盘
代码语言:javascript
复制
分析:键盘录入是一个字节输入流: InputStream in = System.in;
由于输入的都是字符,使用字符流将比较方便(当然字节流也可以,不过麻烦一点)
1.用字符流InputStreamReader将字节流转化
2.再用字符包装流BufferedReader包装一下(当然也可以不包装,不过麻烦一点)

转换流和包装流.png

代码语言:javascript
复制
public class Save2File {
    public static void main(String[] args) throws Exception {

        //数据源----键盘录入字节流转化为字符流后包装成BufferedReader
        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\键盘录入";
        //数据流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\键盘录入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));

        String line = null;
        while ((line=bfr.readLine())!=null){
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}

键盘录入到文件.png

场景二:将键盘录入写入到本地磁盘:指定字符编码

默认字符编码为utf-8,这里使用GBK测试

代码语言:javascript
复制
public class Save2File {
    public static void main(String[] args) throws Exception {
        //数据源----键盘录入字节流转化为字符流后包装成BufferedReader
        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\键盘录入-GKB";
        //数据流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\键盘录入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path),"GBK"));

        String line = null;
        while ((line=bfr.readLine())!=null){
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}

GBK存储.png

可见两者的字节数不同,一个GBK的汉字占2个字节(2*5+\r\n=12) ,一个UTF-8汉字占3个字节(3*5+\r\n=17)

场景3:读取文件输出到控制台
代码语言:javascript
复制
分析:控制台输出是一个字节输出流:PrintStream out = System.out;
由于输出的都是字符,使用字符流将比较方便(当然字节流也可以,不过麻烦一点)
1.用字符流OutputStreamWriter将字节流转化
2.再用字符包装流BufferedWriter包装一下(当然也可以不包装,不过麻烦一点)
代码语言:javascript
复制
public class ReadFile2Console {
    public static void main(String[] args) throws Exception {
        //数据源----本地文件
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md";
        BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
        //数据流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\键盘录入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(System.out));
        String line = null;
        while ((line = bfr.readLine()) != null) {
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}

文件输出到控制台.png

场景4:改变系统流的流向

可以改变系统的录入流(数据来源),和控制台输出流(数据流向)

代码语言:javascript
复制
System.setIn(InputStream 输入流); 自定义System.in数据来源(默认键盘录入)
System.setOut(PrintStream 输出流);自定义System.out数据流向(默认控制台)
代码语言:javascript
复制
public class ReadFile2Console {
    public static void main(String[] args) throws Exception {
        //数据源----本地文件
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md";

        System.setIn(new FileInputStream(path));//将键盘源改为了磁盘文件源
        System.setOut(new PrintStream("F:\\hell.txt"));//将流向控制台改为流向磁盘文件

        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        //数据流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\键盘录入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(System.out));
        String line = null;
        while ((line = bfr.readLine()) != null) {
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}

后记:捷文规范
1.本文成长记录及勘误表

项目源码

日期

备注

V0.1--无

2018-10-10

Java中的字节流与字符流转化

V0.2--无

-

-

2.更多关于我

笔名

QQ

微信

爱好

张风捷特烈

1981462002

zdl1994328

语言

我的github

我的简书

我的CSDN

个人网站

3.声明

1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.10.10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.最常见的几种流
  • 2.流与流之间的相互作用:转换与包装
  • 一、FileOutputStream与FileInputStream
    • 1.FileOutputStream:输出流,写出操作
      • 2.FileInputStream:输入流,读进操作
        • 1)一个一个字节读
        • 2)字节数组方式:
    • 二、使用字节流拷贝
      • 1.使用FileInputStream和FileInputStream拷贝
        • 2.使用包装类BufferedOutputStream和BufferedInputStream拷贝:
        • 三、字节流转化为字符流
          • 场景一:将键盘录入写入到本地磁盘
            • 场景二:将键盘录入写入到本地磁盘:指定字符编码
              • 场景3:读取文件输出到控制台
                • 场景4:改变系统流的流向
                • 后记:捷文规范
                  • 1.本文成长记录及勘误表
                    • 2.更多关于我
                      • 3.声明
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档