java的io流基础篇乱码的原因

1.编码的产生:我们的存储的基本单元是一个byte字节,然而人类的语言太多,无法用一个基本单元来表示,然而为了拆分或者一些相应的翻译工作,导致了编码的产生

2.常见的编码格式

ASCll :用一个字节的低7位共128个来表示,0-31表示控制字符,32-126表示打印字符, ASCll的二进制第一位也就是最高位,目的是用来做奇偶检验的,所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位添1;看到这是似乎对奇偶检验还是较为模糊,不大明白,例如字母A的ASCII码为1000001,若使用偶校验的结果是:01000001,奇检验的结果是11000001;奇偶检验是事先设定好了的,当CPU读取存储的数据时,它会再次把前8位中存储的数据相加,计算结果是否与校验位相一致。从而一定程度上能检测出内存错误,奇偶校验只能检测出错误而无法对其进行修正,同时虽然双位同时发生错误的概率相当低,但奇偶校验却无法检测出双位错,检验到错误的时候,接收数据方就会要求发送方重新传数据

范例:

串行数据在传输过程中,由于干扰,可能使位变为1,(为什么不变0?脉冲)这种情况,称为出现了"误码"。传输中的错误,叫"检错"。发现错误后消除错误叫"纠错"。最简单的检错方法是"奇偶校验",一般在同步传输方式中常采用奇校验,而在异步传输方式中常采用偶校验

ISO-8859-1:由于128字符不够用,于是ISO组织在ASCll的基础上制定一系列的标准来拓展ASCll编码(ISO-8859-1~ISO-8859-15),ISO-8859-1也是作为java web中默认的解析方式

GB2312:全称是《信息交换用汉字编码字符奇基本集》,占两个字节,其中A1~A9是符号区,B0~F7是汉字区

GBK:全称《汉字内码拓展规范》,是对GB2312的拓展,它的编码是与GB2312相兼容的,也就是说用GB2312编码的汉字可以用GBK来编码而不会乱码

GB18030:我国强制标准,可能是单字节 双字节 四个字节,与GB2312编码是兼容的,我国标准,但是使用并不广泛

UTF-16:定义了Unicode(世界上所有的语言都可以用这本字典来相互翻译,是java和xml的基础)在计算机中的存取方法,用两字节来表示Unicode的转换格式,在表示上相对来说简单方便,但是相对于UTF-8来内存空间增大了很多

UTF-8:对每个编码区域有不同的字码长度,不同类型字符可以有1-6个字节组成

UTF-8的编码原则:

如果是一个字节,最高位为0,

如果一个字节以11开头,表示相应的首字节

如果以10开始,则表示他不是首字节,需要向前查找才能得到当前字符的首字符

例如:

1字节 0xxxxxxx

2字节 110xxxxx 10xxxxxx

3字节 1110xxxx 10xxxxxx 10xxxxxx

4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

说明:UTF-8用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去那些控制位(每字节开头的10等),这些x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。 将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数(ASCll标准编码为7位)。

3.io流的编解码

1)读取文件

假如是采用的ascii写的那么不会产生乱码(这也是unicode(\u5F20\u4E09的形式写的转换成任意编码(在能识别的情况下都不会乱码))),假如使用其他编码编写(这里假如是utf-8)文件,在java在没有设置解码的时候,java会默认的按照(gbk)来解码成unicode码(java的jvm就会gbk来解析成utf-16存储),而我们的源文件是使用utf-8写的,所以导致乱码,所以在使用的时候我们会指定按照指定的编码集来解码保证争取的unicode(Char)保存方式,以便的到正确的编解码,在本地文件可以使用EncodingDetect  jar包来获取,这是利用统计学得出的结论,并不是百分百正确,但是准确率在百分之99以上,网络爬虫可以使用cpdetector_1.0.10.jar,同样也是基于统计学

实例

     //简写EncodingDetect的使用方法     String pathname = "F:/test/file1/file2.txt";
        //获取编码格式
        String  encode = EncodingDetect.getJavaEncode(pathname);      System.out.println(encode);             EncodingDetect.readFile(pathname, encode);
//cpdetector网络爬虫获取编码的方法    public static String getFileEncode(String path) {
        /*
         * detector是探测器,它把探测任务交给具体的探测实现类的实例完成。
         * cpDetector内置了一些常用的探测实现类,这些探测实现类的实例可以通过add方法 加进来,如ParsingDetector、
         * JChardetFacade、ASCIIDetector、UnicodeDetector。
         * detector按照“谁最先返回非空的探测结果,就以该结果为准”的原则返回探测到的
         * 字符集编码。使用需要用到三个第三方JAR包:antlr.jar、chardet.jar和cpdetector.jar
         * cpDetector是基于统计学原理的,不保证完全正确。
         */
        CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
        /*
         * ParsingDetector可用于检查HTML、XML等文件或字符流的编码,构造方法中的参数用于
         * 指示是否显示探测过程的详细信息,为false不显示。
         */
        // detector.add(new ParsingDetector(false));
        /*
         * JChardetFacade封装了由Mozilla组织提供的JChardet,它可以完成大多数文件的编码
         * 测定。所以,一般有了这个探测器就可满足大多数项目的要求,如果你还不放心,可以
         * 再多加几个探测器,比如下面的ASCIIDetector、UnicodeDetector等。
         */
        detector.add(JChardetFacade.getInstance());// 用到antlr.jar、chardet.jar
        // ASCIIDetector用于ASCII编码测定
        // detector.add(ASCIIDetector.getInstance());
        // UnicodeDetector用于Unicode家族编码的测定
        // detector.add(UnicodeDetector.getInstance());
        java.nio.charset.Charset charset = null;
        File f = new File(path);
        try {
            charset = detector.detectCodepage(f.toURI().toURL());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (charset != null)
            return charset.name();
        else
            return null;
    }; 

4.url的编解码原则在web核心中写

原文地址:https://www.cnblogs.com/gg128/p/9346589.html

时间: 2024-10-13 16:06:12

java的io流基础篇乱码的原因的相关文章

Java之IO流基础流对象

输入流和输出流是相对于内存设备而言 即将外设中的数据读取到内存中就是输入 将内存中的数据写入到外设中就是输出 字符流的由来: 其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字. 再对这个文字进行操作,其实就是字节流+编码表 字节流的两个顶层父类: 1,InputStream  2,OutputStream 字符流的两个顶层父类: 1,Reader   2,Writer 这些体系的子类都以父类名作为后缀. 而子类名的前缀就是该对象的功能. 如果要操作文字数据,建议

Java IO流基础总结

前言 好久不用Java的IO流,把好多的基础知识都忘了,昨天在写一段代码,发现好多细节都忘了.那天在组织组内代码评审的时候,发现有人在乱用IO流相关的类,所以还是写篇文章,把这个知识点总结一下. IO流类图结构 对于Java这种庞大的体系,我们要学某一块知识点,只有从整体上把握,整体上形成一个知识架构,这样才能更好的把握学习内容和学习方向.所以呢,和别的博文一样,上来就先来一张别的博客贴来的类结构图. 大家先不要被这张图中那么多的类所迷惑了:其实,从这张图来看,结构还是非常清晰的,也是非常简单的

Java之IO流---字节流

1.1 IO流的引入 IO流在很多语言已有体现,诸如C语言的stdio.h,C++中的iostream.Java中的IO流大抵是用于在控制台.磁盘.内存上进行数据的读写操作,完成数据的传递. 我们可以对它进行如下分类: 按处理的数据类型可分为字节流与字符流 按流的流向可分为输入流(in)与输出流(out) 按流的功能可分为节点流(Node)和过滤流(Filter) 本篇侧重于梳理字节流相关的知识,毕竟作为字符流的前辈,它还是非常重要的.下篇继续梳理字符流. 1.2 IO流的继承体系图 大概描述了

Spring Cloud Alibaba | Sentinel: 服务限流基础篇

目录 Spring Cloud Alibaba | Sentinel: 服务限流基础篇 1. 简介 2. 定义资源 2.1 主流框架的默认适配 2.2 抛出异常的方式定义资源 2.3 返回布尔值方式定义资源 2.4 注解方式定义资源 2.5 异步调用支持 3. 规则的种类 3.1 流量控制规则 (FlowRule) 3.2 熔断降级规则 (DegradeRule) 3.3 系统保护规则 (SystemRule) 3.4 访问控制规则 (AuthorityRule) Spring Cloud Al

黑马程序员——Java I/O流基础知识点(File类)

File工具 File类就是用俩将文件或者文件夹封装对象,弥补流对象的不足--流只能操作数据,不能操作文件夹的 封装的是路径!!! 构造方法演示 1.可以将已有的未出现的文件或者文件夹封装成对象. File f1=new File("c:\\abc\\a.txt"): File f2=new File("d:\\abc","ab.txt"打印,会打印路径.:目录分隔符,为了更好地跨平台File. File类常见功能 1,创建 createNewF

Java(Android)线程池---基础篇

1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 newThread(newRunnable(){ 2 3 @Override 4 publicvoidrun(){ 5 // TODO Auto-generated method stub 6 } 7 }).start(); 那你就out太多了,new Thread的弊端如下: a. 每次new Thread新建对象性能差.b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致

JAVA中IO流总结

本文是在学习中的总结,欢迎转载但请注明出处:http://write.blog.csdn.net/postedit/42119261 我想你对JAVA的IO流有所了解,平时使用的也比较的多,但是对于其具体分类和继承体系可能知道的并不多,可能也很少去看相关的API文档,找出其中的关系和各自的应用情形.本文简单对常用的IO流进行分类整理,并简单举例说明其应用.希望本文对你有所帮助. (A)IO流大致分为两种: (1)字节流:对应抽象类为InputStream(输入流)和 OutputStream(输

【JAVA的 IO流之FileInputStream和FileOutputStream】

java的 IO流即输入输出流,流是一组有顺序的,有起点和终点的字节结合,是对数据传输的总称.即数据在两设备间的传输称为流,流的本质是数据传输. IO流可以分为字节流和字符流.给出相应的IO结构图: 在接下来的一段时间里,将会慢慢介绍各种流的使用,本篇博客先介绍字节流的FileOutputStream和相对应的FileInputStream. 一.FileOutputStream(文件输出流) OutputStream是一个抽象类,抽象类必须通过子类实现.现在要向文件里输出就要用FileOutp

Java实现IO通信(服务器篇)

Java实现IO通信(服务器篇) 如何利用java实现我们的通信呢?首先我们了解一下什么是通信?通信的机制是怎样的? 首先来讨论一下什么是通信?通信,指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递,从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法,任意媒质,将信息从某方准确安全地传送到另方.而这里所说的通信,是在同一局域网内,一个用户给其他用户发送信息的过程. 然后通行的机制是怎么样的呢?这里的JavaIO通信是这样的,首先我们需要一台服务器,并有一个或者多个用户