Java学习笔记

编码与解码

2017-02-15  本文已影响68人  奋斗的老王

编码与解码

注意: 以后编码与解码一般我们都使用统一的码表。否则非常容易出乱码

public class Demo {
    
    public static void main(String[] args) throws Exception {
        /*
        String str = "中国";
        byte[] buf = str.getBytes("utf-8");// 平台默认的编码表是gbk编码表。  编码
        System.out.println("数组的元素:"+Arrays.toString(buf)); //
        
        str = new String(buf,"utf-8");  //默认使用了gbk码表去解码。 
        System.out.println("解码后的字符串:"+ str);        
        */
        
        /*String str = "a中国"; // ,0, 97, 78, 45, 86, -3
        byte[] buf = str.getBytes("unicode");  //编码与解码的时候指定 的码表是unicode实际上就是用了utf-16.
        System.out.println("数组的内容:"+ Arrays.toString(buf));
        */
        
        String str = "大家好";
        byte[] buf = str.getBytes(); //使用gbk进行编码
        System.out.println("字节数组:"+ Arrays.toString(buf));  // -76, -13, -68, -46, -70, -61
        
        str = new String(buf,"iso8859-1");
        // 出现乱码之后都可以被还原吗? 
        
        byte[] buf2 = str.getBytes("iso8859-1");
        str = new String(buf2,"gbk"); 

        System.out.println(str);
    }
}

字节流读取中文

public class TestIo {
    public static void main(String[] args) throws IOException {
        readFileByInputStream2("c:\\a.txt");
    }
    private static void readFileByInputStream2(String path) throws IOException {
        FileInputStream fis = new FileInputStream(path);
        int len = 0;

        while ((len = fis.read()) != -1) {
            System.out.print((char) len);
        }

    }
}
public class TestIo {
    public static void main(String[] args) throws IOException {
        readFileByInputStream("c:\\a.txt");
    }
    private static void readFileByInputStream(String path) throws IOException {
        FileInputStream fis = new FileInputStream(path);
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = fis.read(buffer)) != -1) {
            System.out.println(new String(buffer, 0, len, "gbk"));
        }

    }
}
public class TestIo {
    public static void main(String[] args) throws IOException {
        // 该文件默认是gbk编码
        readFileByInputStream("c:\\a.txt");
    }
    private static void readFileByInputStream(String path) throws IOException {
        FileInputStream fis = new FileInputStream(path);
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = fis.read(buffer)) != -1) {
            // 使用utf-8 解码,解错。
            System.out.println(new String(buffer, 0, len, "utf-8"));
        }
    }
}

字节流写出中文

需要编码,可以指定码表。就需要自己把字符串进行编码操作后,把得到的二进制内容通过字节流写入到文件中, 使用String的getBytes方法,无参数的会使用系统默认的码表进行编码,也可以指定码表

public class TestIo {
    public static void main(String[] args) throws IOException {

        String path = "c:\\test.txt";
        writeFileByOutputStream(path, "世界你好");
        readFileByInputStream(path);
    }
    private static void writeFileByOutputStream(String path, String content)
            throws IOException {
        FileOutputStream fos = new FileOutputStream(path);

        // 把字符串进行编码操作,系统默认编码
        byte[] bytes = content.getBytes();
        // 内容通过字节流写入到文件中。
        fos.write(bytes);
        fos.close();
    }
    private static void readFileByInputStream(String path) throws IOException {
        FileInputStream fis = new FileInputStream(path);
        int len = 0;
        byte[] buffer = new byte[1024];

        while ((len = fis.read(buffer)) != -1) {
            // 二进制解码,使用系统默认编码
            System.out.println(new String(buffer, 0, len));
        }
    }
}
public class TestIo {
    public static void main(String[] args) throws IOException {

        String path = "c:\\test.txt";
        writeFileByOutputStream(path, "世界你好");
        readFileByInputStream(path);
    }
    private static void writeFileByOutputStream(String path, String content)
            throws IOException {
        FileOutputStream fos = new FileOutputStream(path);

        // 把字符串进行编码操作
        byte[] bytes = content.getBytes("utf-8");
        // 内容通过字节流写入到文件中。
        fos.write(bytes);
        fos.close();
    }
    private static void readFileByInputStream(String path) throws IOException {
        FileInputStream fis = new FileInputStream(path);
        int len = 0;
        byte[] buffer = new byte[1024];

        while ((len = fis.read(buffer)) != -1) {
            // 二进制解码,使用系统默认编码
            System.out.println(new String(buffer, 0, len,"utf-8"));
        }
    }
}

在明白了字节流也可以正确的处理中文字符之后,就应该明白字符流其实就是字节流在加上系统默认的码表。自动进行了编码和解码的操作。底层还是使用字节流读取文件。通过转换流的学习就可以明白这些道理。

转换流

public class Demo4 {
    public static void main(String[] args) throws IOException {
        File file = new File("c:\\a.txt");
        File fileGBK = new File("c:\\gbk.txt");
        File fileUTF = new File("c:\\utf.txt");
        // 默认编码
        testReadFile(file);
        // 传入gbk编码文件,使用gbk解码
        testReadFile(fileGBK, "gbk");
        // 传入utf-8文件,使用utf-8解码
        testReadFile(fileUTF, "utf-8");
    }
    // 该方法中nputStreamReader使用系统默认编码读取文件.
    private static void testReadFile(File file) throws 
            IOException {
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader ins = new InputStreamReader(fis);
        int len = 0;
        while ((len = ins.read()) != -1) {
            System.out.print((char) len);
        }
        ins.close();
        fis.close();
    }
    // 该方法使用指定编码读取文件
    private static void testReadFile(File file, String encod)
            throws IOException {
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader ins = new InputStreamReader(fis, encod);
        int len = 0;
        while ((len = ins.read()) != -1) {
            System.out.print((char) len);
        }
        ins.close();
        }
}

注意:码表不对应
分别测试:
使用系统默认编码读取utf-8编码文件
使用utf-8编码读取gbk编码文件
使用"gbk”编码读取utf-8文件.
发现都会出现乱码的问题.

// 使用系统默认编码读取utf-8
        testReadFile(fileUTF);
        // 传入gbk编码文件,使用utf-8解码
        testReadFile(fileGBK, "utf-8");
        // 传入utf-8文件,使用"gbk解码
        testReadFile(fileUTF, "gbk"); 
public class TestIo {
    public class Demo4 {
    public static void main(String[] args) throws IOException {
        File file = new File("c:\\a.txt");
        File fileGBK = new File("c:\\gbk.txt");
        File fileUTF = new File("c:\\utf.txt");

        // 写入
        // 使用系统默认码表写入
        testWriteFile(file);
        // 使用gbk编码向gbk文件写入信息
        testWriteFile(fileGBK, "gbk");
        // 使用utf-8向utf-8文件中写入信息
        testWriteFile(fileUTF, "utf-8");
    
        // 读取
        // 默认编码
        testReadFile(file);
        // 传入gbk编码文件,使用gbk解码
        testReadFile(fileGBK, "gbk");
        // 传入utf-8文件,使用utf-8解码
        testReadFile(fileUTF, "utf-8");

    }

    // 使用系统码表将信息写入到文件中
    private static void testWriteFile(File file) throws IOException {
        FileOutputStream fos = new FileOutputStream(file);
        OutputStreamWriter ops = new OutputStreamWriter(fos);
        ops.write("中国");
        ops.close();
    }

    // 使用指定码表,将信息写入到文件中
    private static void testWriteFile(File file, String encod)
            throws IOException {
        FileOutputStream fos = new FileOutputStream(file);
        OutputStreamWriter ops = new OutputStreamWriter(fos, encod);
        ops.write("中国");
        ops.close();
    }

    // 该方法中nputStreamReader使用系统默认编码读取文件.
    private static void testReadFile(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader ins = new InputStreamReader(fis);
        int len = 0;
        while ((len = ins.read()) != -1) {
            System.out.print((char) len);
        }
        ins.close();
    
    }

    // 该方法适合用指定编码读取文件
    private static void testReadFile(File file, String encod)
            throws IOException {
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader ins = new InputStreamReader(fis, encod);
        int len = 0;
        while ((len = ins.read()) != -1) {
            System.out.print((char) len);
        }
    
        ins.close();
    }
}

注意: 码表不对应的问题
分别测试:
向GBK文件中写入utf-8编码的信息
向utf文件中写入gbk编码的信息
发现文件都有问题,无法正常的读取了.

public static void main(String[] args) throws IOException {
        File file = new File("c:\\a.txt");
        File fileGBK = new File("c:\\gbk.txt");
        File fileUTF = new File("c:\\utf.txt");

        // 写入
        // // 使用系统默认码表写入
        // testWriteFile(file);
        // // 使用gbk编码向gbk文件写入信息
        // testWriteFile(fileGBK, "gbk");
        // // 使用utf-8向utf-8文件中写入信息
        // testWriteFile(fileUTF, "utf-8");

        testWriteFile(fileGBK);
        // 向GBK文件中写入utf-8编码的信息
        testWriteFile(fileGBK, "utf-8");
        // 向utf文件中写入gbk编码的信息
        testWriteFile(fileUTF, "gbk");

        // 读取
        // 默认编码
        testReadFile(file);
        // 传入gbk编码文件,使用gbk解码
        testReadFile(fileGBK, "gbk");
        // 传入utf-8文件,使用utf-8解码
        testReadFile(fileUTF, "utf-8");

    }

InputStreamReader:字节到字符的桥梁。
OutputStreamWriter:字符到字节的桥梁。

它们有转换作用,而本身又是字符流。所以在构造的时候,需要传入字节流对象进来。
构造函数:
InputStreamReader(InputStream)
通过该构造函数初始化,使用的是本系统默认的编码表GBK。
InputStreamReader(InputStream,String charSet)
通过该构造函数初始化,可以指定编码表。
OutputStreamWriter(OutputStream)
通过该构造函数初始化,使用的是本系统默认的编码表GBK。
OutputStreamWriter(OutputStream,String charSet)
通过该构造函数初始化,可以指定编码表。
注意:
操作文件的字符流对象是转换流的子类。

注意:
在使用FileReader操作文本数据时,该对象使用的是默认的编码表。
如果要使用指定编码表时,必须使用转换流。

如果系统默认编码是GBK的:
FileReader fr = new FileReader("a.txt");//操作a.txt的中的数据使用的本系统默认的GBK。
操作a.txt中的数据使用的也是本系统默认的GBK。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
这两句的代码的意义相同。
但是:如果a.txt中的文件中的字符数据是通过utf-8的形式编码。使用FileReader就无能为力,那么在读取时,就必须指定编码表。那么转换流必须使用。
InputStreamReader isr =
new InputStreamReader(new FileInputStream("a.txt"),"utf-8");

上一篇 下一篇

猜你喜欢

热点阅读