Java转换流

文章目录

引入情况1:

使用FileReader 读取项目中的文本文件。由于IDEA设置中针对项目设置了UTF-8编码,当读取Windows系统中创建的文本文件时,如果Windows系统默认的是GBK编码,则读入内存中会出现乱码。

java 复制代码
import java.io.FileReader;
import java.io.IOException;

public class Problem {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("E:\\File_GBK.txt");
        int data;
        while ((data = fileReader.read()) != -1) {
            System.out.print((char)data);
        }
        fileReader.close();
    }
}

输出结果:
���

那么如何读取GBK编码的文件呢?

引入情况2:

针对文本文件,现在使用一个字节流进行数据的读入,希望将数据显示在控制台上。此时针对包含中文的文本数据,可能会出现乱码。

转换流的理解

作用:转换流是字节与字符间的桥梁!

具体来说:

InputStreamReader

  • 转换流java.io.InputStreamReader,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

  • 构造器

    • InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。
    • InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。
  • 举例

java 复制代码
//使用默认字符集
InputStreamReader isr1 = new InputStreamReader(new FileInputStream("in.txt"));
//使用指定字符集
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");

示例代码:

java 复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        // 定义文件路径,文件为gbk编码
        String fileName = "E:\\file_gbk.txt";
        //方式1:
        // 创建流对象,默认UTF8编码
        InputStreamReader isr1 = new InputStreamReader(new FileInputStream(fileName));
        // 定义变量,保存字符
        int charData;
        // 使用默认编码字符流读取,乱码
        while ((charData = isr1.read()) != -1) {
            System.out.print((char)charData); // ��Һ�
        }
        isr1.close();
		
        //方式2:
        // 创建流对象,指定GBK编码
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream(fileName) , "GBK");
        // 使用指定编码字符流读取,正常解析
        while ((charData = isr2.read()) != -1) {
            System.out.print((char)charData);// 大家好
        }
        isr2.close();
    }
}

OutputStreamWriter

  • 转换流java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

  • 构造器

    • OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。
    • OutputStreamWriter(OutputStream in,String charsetName): 创建一个指定字符集的字符流。
  • 举例:

java 复制代码
//使用默认字符集
OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("out.txt"));
//使用指定的字符集
OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("out.txt") , "GBK");

示例代码:

java 复制代码
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        // 定义文件路径
        String FileName = "E:\\out_utf8.txt";
        // 创建流对象,默认UTF8编码
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));
        // 写出数据
        osw.write("你好"); // 保存为6个字节
        osw.close();

        // 定义文件路径
        String FileName2 = "E:\\out_gbk.txt";
        // 创建流对象,指定GBK编码
        OutputStreamWriter osw2 = new OutputStreamWriter(new                     
                                                FileOutputStream(FileName2),"GBK");
        // 写出数据
        osw2.write("你好");// 保存为4个字节
        osw2.close();
    }
}

练习

把当前module下的《好好学习.txt》字符编码为GBK,复制到电脑桌面目录下的《寄语.txt》,

字符编码为UTF-8。

在当前module下的文本内容:

java 复制代码
六项精进:
(一)付出不亚于任何人的努力
(二)要谦虚,不要骄傲
(三)要每天反省
(四)活着,就要感谢
(五)积善行、思利他
(六)不要有感性的烦恼

代码:

java 复制代码
public class InputStreamReaderDemo {

    @Test
    public void test() {
        InputStreamReader isr = null;
        OutputStreamWriter osw = null;
        try {
            isr = new InputStreamReader(new FileInputStream("好好学习.txt"),"gbk");

            osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Desktop\\寄语.txt"),"utf-8");

            char[] cbuf = new char[1024];
            int len;
            while ((len = isr.read(cbuf)) != -1) {
                osw.write(cbuf, 0, len);
                osw.flush();
            }
            System.out.println("文件复制完成");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (isr != null)
                    isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (osw != null)
                    osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}
相关推荐
考虑考虑25 分钟前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯1 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路5 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还8 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev10 小时前
GreenDAO → Room
android·java·kotlin
亦暖筑序15 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
敲代码的彭于晏16 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev17 小时前
ButterKnife → ViewBinding
android·java·kotlin
像我这样帅的人丶你还1 天前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩1 天前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构