Java学习笔记(二十四)

在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第二十四篇博客。

本篇博客介绍了Java的字符流。

本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11

目录

字符流

出现字符流的原因

编码表

字符串的编码解码问题

字符流的编码解码问题

字符流写数据的五种方式

字符流读数据的二种方式

字符流复制Java文件

字符缓冲流

字符缓冲流特有功能

IO流小结


字符流

出现字符流的原因

字节流操作中文等语言不是特别方便,因此提供了字符流。字符流 = 字节流 + 编码表

字节流复制文件出现中文时,结果没有问题,因为最终底层操作通过编码表自动拼接成中文。

编码表

计算机存储的信息都是二进制表示的,屏幕上的内容都是进行了转换的结果。

按照某种规则,将字符存储到计算机中,称为编码。将存储到计算机中的二进制数按照某种规则解析显示出来,就是解码。使用哪种码进行编码,就使用哪种码进行解码,否则会出现乱码。

字符编码是字符与数字的对应规则。

字符集是系统支持的所有字符的集合,包括各国语言文字,标点符号,数字等。计算机要准确存储各种字符集符号,就要进行字符编码,常见的有ASCII字符集,GBXXX字符集,Unicode字符集等。

ASCII码是美国信息交换标准代码,基于拉丁字母,用于显示现代英语。包括控制字符和可显示字符(大小写,数字,英文符号等)。

GB2312是信息交换用汉字编码字符集。用两个字节表示一个汉字。组合了7000多个简体汉字,并兼容ASCII码。

GBK是汉字内码扩展规范,是最常用的中文码表,在GB2312的标准上进行扩展。收录了2万多个汉字,兼容GB2312,支持繁体汉字。

GB18030是信息技术 中文编码字符集,收录超过7万个汉字,用多字节编码,每个字可以有1个,2个或4个字节组成。支持繁体字和我国少数民族文字。

Unicode字符集是为了表达任意语言的任意字符设计的,称为统一码。最多4个字节来表示每个字母,符号,文字。有UTF-8,UTF-16和UTF-32三种方案,最常用的是UTF-8。

UTF-8编码可以表示Unicode标准中的任意字符。所有互联网协议都支持UTF-8编码。使用1-4个字节编码。128个ASCII码字符使用一个字节,拉丁文等字符使用两个字节,大部分常用字,包括中文,使用三个字节,极少使用的用四个字节。

字符串的编码解码问题

byte[] getBytes()使用平台的默认字符集将String编码,结果存至byte数组中。

byte[] getBytes(String charsetName)使用指定字符集将String编码,结果存至byte数组中。

String(byte[] bytes)使用默认字符集解码指定的字节数组。

String(byte[] bytes,String charsetName)通过指定字符集解码指定的字节数组。

本机使用IDEA所用编码为UTF-8。

import java.io.UnsupportedEncodingException;
public class codetest1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "奥运会";
        byte[] byte1 = s.getBytes();
        System.out.println(new String(byte1));
        System.out.println(new String(byte1,"GBK"));

        byte[] byte2 = s.getBytes("GBK");
        System.out.println(new String(byte2));
        System.out.println(new String(byte2,"GBK"));
    }
}

程序的输出是:

奥运会
濂ヨ繍浼�
���˻�
奥运会

字符流的编码解码问题

Reader是字符输入流的抽象类。Writer是字符输出流的抽象类。

字符流中和编码解码问题相关的输入类是InputStreamReader,相关输出类是OutputStreamWriter

使用这两个类也要导包,import java.io.InputStreamReaderimport java.io.OutputStreamWriter。

import java.io.*;

public class codetest2 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("test3.txt"),"UTF-8");
        osw1.write("上午和下午");
        osw1.close();
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("test3.txt",true),"GBK");
        osw2.write("上午和下午");
        osw2.close();

        InputStreamReader isr1 = new InputStreamReader(new FileInputStream("test3.txt"),"UTF-8");
        int ch;
        while((ch = isr1.read()) != -1){
            System.out.print((char)ch);
        }
        System.out.println();
        isr1.close();

        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("test3.txt"),"GBK");
        while((ch = isr2.read()) != -1){
            System.out.print((char)ch);
        }
        System.out.println();
        isr2.close();

    }
}

程序使用OutputStreamWriter以UTF-8和GBK向文件中写入上午和下午。随后使用InputStreamReader从文件中以UTF-8和GBK的方式读入。

程序的输出是:

上午和下午���������
涓婂崍鍜屼笅鍗埳衔绾拖挛�
test3.txt的内容是:

涓婂崍鍜屼笅鍗埳衔绾拖挛?

字符流写数据的五种方式

void write(int c)写入一个字符,ASCII码值为c。

void write(char[] cbuf)写入一个字符数组。

void write(char[] cbuf,int off,int len)将cbuf从off开始的len个字符写入。

void write(String str)写入一个字符串。

void write(String str,int off,int len)将str从off开始的len个字符写入。

flush()刷新流,将数据保存,之后还可以继续写入数据。

close()关闭流,释放资源。关闭前会刷新,关闭后无法继续写数据。

import java.io.*;
public class writetest6 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("test3.txt"));
        osw.write(50);
        char[] ch = new char[]{'a','b','c','d','e'};
        osw.write(ch);
        osw.write(ch,2,2);

        osw.write("北京冬奥会");
        osw.write("Beijing 2022",2,3);
        osw.close();
    }
}

程序无输出,文件中的内容是:

2abcdecd北京冬奥会iji

字符流读数据的二种方式

int read()一次读一个字符数据,并将其码值返回。

int read(char[] cbuf)一次读一个字符数组数据,并返回读取的字符数量。

读到文件结尾后都返回-1。

import java.io.*;
public class readtest3 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr1 = new InputStreamReader(new FileInputStream("test3.txt"));
        int ch;
        while((ch = isr1.read()) != -1){
            System.out.print((char)ch);
        }
        System.out.println();
        isr1.close();

        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("test3.txt"));
        char[] chr = new char[1024];
        int len;
        while((len = isr2.read(chr)) != -1){
            System.out.println(new String(chr, 0, len));
        }
        isr2.close();
    }
}

程序的输出是:

2abcdecd北京冬奥会iji
2abcdecd北京冬奥会iji

字符流复制Java文件

字符流的名字比较长,我们通常使用本地默认编码。因此Java提供了对应子类。

FileReader用于读取字符文件,构造方法为FileReader(String fileName),需要导包,import java.io.FileReader

FileWriter用于写入字符文件,构造方法为FileWriter(String fileName),需要导包,import java.io.FileWriter

import java.io.*;
public class readwritetest2 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("pokertest2.Java");
        FileWriter fw = new FileWriter("pokertest3.Java");
        char[] chs = new char[1024];
        int len;
        while((len = fr.read(chs)) != -1){
            fw.write(chs,0,len);
        }

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

同样使用两个流处理,一个读一个写。程序无输出。由于内容太长,就不再展示,复制成功。

字符缓冲流

BufferedWriter将文本写入字符输出流,缓冲字符以提供高效写入。可以指定缓冲区大小,或者使用默认大小。默认值足够大。需要导包,import java.io.BufferedWriter。构造方法是:

BufferedWriter(Writer out)

BufferedReader从字符输入流读取文本,缓冲字符以提供高效读取。可以指定缓冲区大小或使用默认大小,默认值足够大。需要导包,import java.io.BufferedReader。构造方法是:

BufferedReader(Reader in)

import java.io.*;
public class buffertest2 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("test3.txt"));
        bw.write(97);
        bw.write(98);
        bw.write(99);
        bw.write(100);
        bw.write(10);
        bw.write("Hello Java");
        bw.write("\n");
        bw.close();

        BufferedReader br = new BufferedReader(new FileReader("test3.txt"));
        char[] chr = new char[1024];
        int len = 0;
        while((len = br.read(chr)) != -1){
            System.out.print(new String(chr, 0, len));
        }
        br.close();
    }
}

程序先向一个文件中写数据,然后从这个文件中读数据。

程序的输出是:

abcd
Hello Java

文件操作也成功。

字符缓冲流特有功能

BufferedWriter的void newLine()进行换行。

BufferedReader的public String readLine()读一行文字,将结果返回。结果不包含换行符,到末尾后返回null。

import java.io.*;
public class bufferreadwrite {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("test3.txt"));
        bw.write("Hello Java");
        bw.newLine();
        bw.write("2022 07 18");
        bw.newLine();
        bw.write("After 17");
        bw.newLine();
        bw.write("This is in JDK11");
        bw.close();

        BufferedReader br = new BufferedReader(new FileReader("test3.txt"));
        String s;
        while((s = br.readLine()) != null){
            System.out.println(s);
        }
        br.close();
    }
}

程序同样先向一个文件写数据,然后从这个文件中读数据。

程序的输出是:

Hello Java
2022 07 18
After 17
This is in JDK11

文件内容也成功改变。

import java.io.*;
public class buffertest3 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("pokertest3.java"));
        BufferedReader br = new BufferedReader(new FileReader("pokertest2.java"));

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

可以据此改进复制Java文件的程序,程序复制成功。

IO流小结

字节流分为字节输入流InputStream和字节输出流OutputStream。InputStream包括FileInputStreamBufferedInputStream。OutputStream包括FileOutputStreamBufferedOutputStream

字符流包括字符输入流Reader和字符输出流Writer。Reader包括InputStreamReaderBufferedReader,InputStreamReader包括FileReader。Writer包括OutputStreamWriterBufferedWriter,OutputStreamWriter包括FileWriter

一般使用字节缓冲流和字符缓冲流。另外,IO流的名字容易混。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值