【JAVA】编码表,字符流,对象流,其他流(一)

简介: 【JAVA】编码表,字符流,对象流,其他流

1 编码表


1.1 思考:


  • 既然字节流可以操作所有文件,那么为什么还要学习字符流 ?
  • 如果使用字节流 , 把文本文件中的内容读取到内存时, 可能会出现乱码
  • 如果使用字节流 , 把中文写入文本文件中 , 也有可能会出现乱码

1.2 编码表介绍


  • 计算机中储存的信息都是用二进制数据表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果
  • 按照编码表规则,将字符存储到计算机中,称为编码。
  • 按照同样的编码表规则,将存储在计算机中的二进制数据解析显示出来,称为解码 。
  • 编码和解码使用的码表必须一致,否则会导致乱码。
  • 简单理解:
  • 存储一个字符a,首先需在码表中查到对应的数字是97,然后按照转换成二进制的规则进行存储。称为编码
  • 读取的时候,先把二进制解析出来,再转成97,通过97查找早码表中对应的字符是a。称为解码
  • ASCII码表
  • ASCII(American Standard Code for Information Interchange,美国信息交换标准码表):
  • 包括了数字字符,英文大小写字符和一些常见的标点符号字符。
  • image.png
  • 注意:ASCII码表中是没有中文的。
  • GBK码表:
  • window系统默认的码表。兼容ASCII码表,也包含了21003个汉字,并支持繁体汉字以及部分日韩文字
  • 注意:GBK是中国的码表,一个中文以两个字节的形式存储。但不包含世界上所有国家的文字。
Unicode码表:
  • 由国际组织ISO 制定,是统一的万国码表,计算机科学领域里的一项业界标准,容纳世界上大多数国家的所有常见文字和符号。
  • 但是因为表示的字符太多,所以Unicode码表中的数字不是直接以二进制的形式存储到计算机的,会先通过UTF-7,UTF-7.5,UTF-8,UTF-16,以及 UTF-32的编码方式再存储到计算机,其中最为常见的就是UTF-8。
  • 注意: Unicode是万国码表,以UTF-8编码后一个中文以三个字节的形式存储

1.3 编码表小结


image.png

image.png

1.4 字节流读中文出现码的原码


  • 因为字节流一次读一个字节,而不管GBK还是UTF-8一个中文都是多个字节,用字节流每次只能读其中的一部分,所以就会出现乱码问题

2 字符输出流


2.1 字符流输出介绍


  • Writer类
  • 写入字符流的最顶层的类 , 是一个抽象类 ,不能实例化 , 需要使用其子类FileWriter类
  • FileWriter类 : 用来写入字符文件的便捷类

2.2 FileWriter的成员


  • 构造方法 :
  • public FileWriter(File file) : 往指定的File路径中写入数据
  • public FileWriter(String fileName) : 往指定的String路径中写入数据
  • 成员方法 :
  • image.png
flush() 刷新流,还可以继续写数据
close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据

2.3 FileWriter写数据的步骤


  • 1 创建字符输出流对象
  • 注意事项:
    如果文件不存在,就创建。但是要保证父级路径存在。
    如果文件存在就清空
  • 2 写数据
  • 注意事项:
    写出int类型的整数,实际写出的是整数在码表上对应的字母。
    写出字符串数据,是把字符串本身原样写出。
  • 3 释放资源
  • 注意事项:
    每次使用完流必须要释放资源。
package com.itheima.writer_demo;
import java.io.FileWriter;
import java.io.IOException;
/*
    Writer类 : 写入字符流的最顶层的类 , 是一个抽象类 ,不能实例化
    需要使用其子类FileWriter类
    FileWriter类 : 用来写入字符文件的便捷类
    构造方法 :
        public FileWriter(File file) : 往指定的File路径中写入数据
        public FileWriter(String fileName) : 往指定的String路径中写入数据
    成员方法
        void write​(int c)  写一个字符
        void write​(char[] cbuf)  写入一个字符数组
        void write​(char[] cbuf, int off, int len)  写入字符数组的一部分
        void write​(String str) 写一个字符串
        void write​(String str, int off, int len) 写一个字符串的一部分
        flush() 刷新流,还可以继续写数据
        close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
 */
public class WriterDemo1 {
    public static void main(String[] args) throws IOException {
        // 创建字符输出流对象
        // 如果文件不存在会创建一个空的文件
        // 如果文件存在 , 会把文件中的内容清空
        FileWriter fw = new FileWriter("day12_demo\\charstream2.txt");
        // 写数据
        fw.write('a');
        fw.write('b');
        // 刷新流 , 把流中的数据刷到硬盘中 , 刷新之后可以继续写数据
        // fw.flush();
        // 释放资源
        // 关闭流 , 但是会先刷新流
        fw.close();
        // 一旦关闭流无法写数据
        // fw.write('c');
    }
}
package com.itheima.writer_demo;
import java.io.FileWriter;
import java.io.IOException;
/*
    Writer类 : 写入字符流的最顶层的类 , 是一个抽象类 ,不能实例化
    需要使用其子类FileWriter类
    FileWriter类 : 用来写入字符文件的便捷类
    构造方法 :
        public FileWriter(File file) : 往指定的File路径中写入数据
        public FileWriter(String fileName) : 往指定的String路径中写入数据
    成员方法
        void write​(int c)  写一个字符
        void write​(char[] cbuf)  写入一个字符数组
        void write​(char[] cbuf, int off, int len)  写入字符数组的一部分
        void write​(String str) 写一个字符串
        void write​(String str, int off, int len) 写一个字符串的一部分
        flush() 刷新流,还可以继续写数据
        close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
 */
public class WriterDemo2 {
    public static void main(String[] args) throws IOException {
        // 创建字符输出流对象
        FileWriter fw = new FileWriter("day12_demo\\charstream2.txt");
        // 写数据
//        void write​(int c)  写一个字符
//        fw.write('a');
//        fw.write('b');
//        fw.write('c');
//        void write​(char[] cbuf)  写入一个字符数组
        char[] chs = {'a', 'b', 'c', 'd', 'e'};
//        fw.write(chs);
//        void write​(char[] cbuf, int off, int len)  写入字符数组的一部分
//        fw.write(chs , 2 , 3);
//        void write​(String str) 写一个字符串
//        fw.write("abcadaasda");
//        void write​(String str, int off, int len) 写一个字符串的一部分
//        fw.write("abnacna", 3, 2);
        // 释放资源
        fw.close();
    }
}

2.4 字符输出流练习


package com.itheima.writer_demo;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
/*
    需求 : 将用户键盘录入的用户名和密码保存到本地实现永久化存储。
    要求 : 用户名和密码在文件中各占一行
    步骤:
        1 用户键盘录入用户名
        2 创建字符输出流对象
        3 将用户名和密码写到本地文件中
 */
public class WriterTest {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        // 创建字符输出流对象
        FileWriter fw = new FileWriter("day12_demo\\user.txt");
        // 往文件中写入用户名和密码
        fw.write(username);
        // 换行
        fw.write("\r\n");
        fw.write(password);
        // 刷新
        fw.flush();
        // 释放资源
        fw.close();
    }
}

3 字符输入流


3.1 字节输入流介绍


  • Reader类 :
  • 读取字符流的最顶层的类 , 是一个抽象类 ,不能实例化
  • 需要使用其子类FileReader类
  • FileReader类 :
  • 用来读取字符文件的便捷类

3.2 FileReader的成员


  • 构造方法 :
  • public FileReader(File file) : 从指定的File路径中读取数据
  • public FileReader(String fileName) : 从指定的String路径中读取数据
  • 成员方法 :
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据
package com.itheima.reader_demo;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
    Reader类 : 读取字符流的最顶层的类 , 是一个抽象类 ,不能实例化
    需要使用其子类FileReader类
    FileReader类 : 用来读取字符文件的便捷类
    构造方法 :
        public FileReader(File file) : 从指定的File路径中读取数据
        public FileReader(String fileName) : 从指定的String路径中读取数据
    成员方法 :
        int read​() : 一次读一个字符数据
        int read​(char[] cbuf)   : 一次读一个字符数组数据
 */
public class ReaderDemo1 {
    public static void main(String[] args) throws IOException {
        // 创建字符输入流对象
        FileReader fr = new FileReader("day12_demo\\charstream.txt");
        // 一次读一个字符数据
        int ch;
        while ((ch = fr.read()) != -1) {
            System.out.print((char) ch);
        }
        // 释放资源
        fr.close();
    }
}
package com.itheima.reader_demo;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
    Reader类 : 读取字符流的最顶层的类 , 是一个抽象类 ,不能实例化
    需要使用其子类FileReader类
    FileReader类 : 用来读取字符文件的便捷类
    构造方法 :
        public FileReader(File file) : 从指定的File路径中读取数据
        public FileReader(String fileName) : 从指定的String路径中读取数据
    成员方法 :
        int read​() 一次读一个字符数据
        int read​(char[] cbuf)  一次读一个字符数组数据
 */
public class ReaderDemo2 {
    public static void main(String[] args) throws IOException {
        // 创建字符输入流对象
        FileReader fr = new FileReader("day12_demo\\charstream.txt");
        // 一次读一个字符数组数据
        char[] chs = new char[1024];
        int len;
        while ((len = fr.read(chs)) != -1) {
            System.out.println(new String(chs, 0, len));
        }
        // 释放资源
        fr.close();
    }
}
相关文章
|
23天前
|
Java
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
53 4
|
19天前
|
Java
Java实现随机生成某个省某个市的身份证号?如何编码?
【10月更文挑战第18天】Java实现随机生成某个省某个市的身份证号?如何编码?
68 5
|
23天前
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
49 2
|
30天前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
65 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
1月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
32 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
70 1
|
2月前
|
存储 移动开发 Java
java核心之字符串与编码
java核心之字符串与编码
20 2
|
3月前
|
Java PHP 开发者
PHP中的异常处理:Java常见的编码方式
在PHP开发中,掌握异常处理至关重要,它有助于预见并管理运行时错误,避免用户体验受损或数据丢失。本文介绍PHP异常处理的基本概念与实践,包括try-catch语句的使用,以及如何通过抛出和捕获异常来增强代码的健壮性和可靠性。通过示例展示如何避免常见错误,如除数为零的情况,并探讨多catch块和finally语句的高级用法,帮助开发者提升程序稳定性与可维护性。[总字符数:238]
27 0
|
3天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
12天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
下一篇
无影云桌面