-
2018-12-29 13:45:38
首先,计算机内部只能存储二进制数据,即1和0的bit位。所以,我们要让计算机显示各种字符,就必须要对字符进行编码,让每一个字符对应一个数字编码。而之所以会造成乱码现象,是因为当初创建文件的时候采用的编码方式,和打开时的编码方式不一样,这样的对应关系就乱了,于是我们看到的就是乱七八糟的。
---------------------
原文:https://blog.csdn.net/charles_neil/article/details/70942840文本文件编码有四种:
ANSI:系统预设的标准文字储存格式。
UTF-8:UTF意为通用字集转换格式(Universal Character Set Transformation Format),UTF-8是Unicode的8位元格式。如果使用只能在同类位元组内支持8个位元的重要资料一类的旧式传输媒体,可选择UTF-8格式
Unicode:世界上所有主要指令文件的联集,包括商业和个人电脑所使用的公用字集。当采用Unicode格式储存文件时,可使用Unicode控制字符辅助说明语言的文字覆盖范围,
Unicode big endian:在Big-endian处理器(如苹果Macintosh电脑)上建立的Unicode文件中的文字位元组(存放单位)排列顺序,与在Intel处理器上建立的文件的文字位元组排列顺序相反。
https://blog.csdn.net/kaibing/article/details/78199743
2、
源码字符集(the source character set):源码文件是使用何种编码保存的。
执行字符集(the execution character set):可执行程序内保存的是何种编码(程序执行时内存中字符串编码)。
源码字符集很容易理解,就是我们源代码的编码。为了我们的代码能够跨平台,源文件要保存为带 BOM 的 utf-8。3、
问题:QString str( QObject::tr("中文") ) 能用么?
答案:不能,tr( ) 中只能是英文。
因为QT5版本取消了QTextCodec::setCodecForTr()方法。并且你要明白QObject::tr是干嘛的。它是用于程序国际化使用的,也就可以界面文字翻译成不同的语言。你如果使用QObject::tr,你应该全部用英文表示,然后后面借助Linguist翻译成中文,就不会乱码了。详细请搜索“qt国际化"。
更多相关内容 -
Java判断文本文件编码格式以及读取
2020-10-19 15:48:45如果很多时候我们没有约定好文件格式,我们就难以读取文件内容,此时,我们就需要一个工具来探测所读文本的编码格式,此工具可以允许用户读取诸如utf-8,gbk,gb2312一类的文件格式。内置了一些常用的探测实现类,... -
文本文件编码探查.zip
2020-03-09 16:42:19文本类文件编码格式有以下几种: 1)ASCII',这是西文字母 2)ANSI(GBK)',这是兼容西文字母的中文格式 3)UTF-8',这是不带BOM前导标志的UTF8编码 4)UTF-16LE',这是文件中带有UTF-16LE前导标志的标准的UNIcode... -
文本文件编码转换工具(TextEncodeConvert)V2.1安装版
2019-07-30 04:20:37TextEncodeConvert是一款好用的文本文件编码转换工具,该工具界面简洁,操作方便,体积小,功能不错,欢迎下载体验。 TextEncodeConvert功能: 1、本产品可以对文本文件进行编码转换。 例如:SJIS(932)-... -
QT读写文本文件编码设置
2021-12-08 19:33:22QT读写文本文件编码设置 一、编码知识科普 Qt常见的两种编码是:UTF-8和GBK ★UTF-8:Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一...QT读写文本文件编码设置
一、编码知识科普
Qt常见的两种编码是:UTF-8和GBK
★UTF-8:Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。
★GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。GBK是GB2312的扩展,除了兼容GB2312外,它还能显示繁体中文,还有日文的假名。
★GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:
GBK、GB2312--Unicode--UTF8
UTF8--Unicode--GBK、GB2312
★在简体中文windows系统下,ANSI编码代表GBK/GB2312编码,ANSI通常使用0x800xFF范围的2个字节来表示1个中文字符。0x000x7F之间的字符,依旧是1个字节代表1个字符。Unicode(UTF-16)编码则所有字符都用2个字节表示。三、编码转换
Windows自带的记事本,无法查看UTF-8编码的文件到底有无BOM,需要使用其他文件编辑器,比如Notepad++或者SublimeText。
四、QString显示中文乱码的原因
- 读取文件编码类型设置错误
Windows系统本地字符编码(Local字符集)为GBK 即ANSI(文本文档)。编译器分析出源文件字符编码之后,会进行解码再编码,将源字符集转码成执行字符集。执行字符集一般默认为使用本地字符编码(Local字符集),若指定UTF-8编码,而本地实际为GBK时变为乱码。 - 文本中存在不同的编码格式的文本
比如存在ANSI(GBK)和UTF-8 无论通过哪一种读写都会出现乱码
若txt文件是ansi格式 其中存在UTF-8编码的字符串 则读取这部分字符时出现乱码。
可通过NotePad++切换编码确定那一部分是ANSI或UTF-8
先通过ANSI(GBK) 读取所有字符串 获得UTF-8的字符串otherLineStr后进行转换、然后重新 写入UTF-8的文件中
otherLineStr = otherLineStr.toLocal8Bit().data();
注意:当写入文件中的字符串有中文时,qt默认ANSI编码
五、设置字符读写字符集
Qt5可以设置Local字符集,GBK/UTF-8QTextStream stream(&readFile); stream.setCodec("GBK"); QTextCodec* codec = QTextCodec::codecForName("UTF-8"); strAll = codec->toUnicode(readFile.readAll()); QTextCodec *codec = QTextCodec::codecForName("UTF-8");//或者"GBK",不分大小写 QTextCodec::setCodecForLocale(codec); //全局编码设置
六、QString简介
Qt5中QString内部采用unicode字符集,utf-16编码。构造函数QString::QString(const char *str)默认使用fromUtf8(),从文件中读取时ANSI(GBK)的文件使用fromLocal8Bit(), 将str所指的执行字符集从utf-8转码成utf-16。
由上面fromUtf8()可知,QString需要执行字符集编码为utf-8,然后以utf-8进行解码,再编码为utf-16才能获得正确的字符编码。https://www.cnblogs.com/sggggr/p/12797951.html
- 读取文件编码类型设置错误
-
文本文件编码格式
2022-02-08 10:34:01文本文件存储的内容是基于 字符编码 的文件,常见的编码有 ASCII 编码,UNICODE 编码等 Python 2.x 默认使用 ASCII 编码格式,故Python不支持中文 Python 3.x 默认使用 UTF-8 编码格式 ASCII 编码 计算机中...文本文件存储的内容是基于 字符编码 的文件,常见的编码有 ASCII 编码,UNICODE 编码等
Python 2.x 默认使用 ASCII 编码格式,故Python不支持中文
Python 3.x 默认使用 UTF-8 编码格式
ASCII 编码
- 计算机中只有 256 个 ASCII 字符
- 一个 ASCII 在内存中占用 1 个字节 的空间
- 8 个 0/1 的排列组合方式一共有 256 种,也就是 2 ** 8
UTF-8 编码格式
- 计算机中使用 1~6 个字节 来表示一个 UTF-8 字符,涵盖了 地球上几乎所有地区的文字
- 大多数汉字会使用 3 个字节 表示
- UTF-8 是 UNICODE 编码的一种编码格式
-
易语言-判断文本文件是否为UTF-8编码
2021-06-29 16:54:11判断给定缓冲区是否可能是UTF-8编码。windows7旗舰版notepad.exe代码。 andyup -
C#实现获取文本文件的编码的一个类(区分GB2312和UTF8)
2020-09-04 04:41:18主要介绍了C#实现获取文本文件的编码一个类,本文给出类可以自动区分GB2312和UTF8,并同时给出了使用方法,需要的朋友可以参考下 -
QueryCode.vbs 文本文件编码查询工具
2020-09-05 21:33:35使用vbs实现文本文件编码的查询的代码,需要的朋友可以参考下。 -
C#读写指定编码格式的文本文件
2020-09-02 16:58:35主要为大家详细介绍了C#读写指定编码格式文本文件的方法,感兴趣的小伙伴们可以参考一下 -
自动识别不同编码的文本文件
2017-11-02 10:23:10从国外网站下载的文件类,支持ASCII, UTF-8, Unicode 16 little/big endian四种格式。 -
请问文本文件的中文字符编码形式?
2020-08-25 20:38:18问下,文本文件中的中文字符是以那种形式的字符编码方式存在的? 比如:”我是谁“这三个字以什么编码形式保存的? -
文本文件编码批量转换工具
2021-07-02 13:57:44用于文本文件编码批量转换,可以实现编码格式之间相互转换,注意不能转换只读文件!!!只读文件会导致软件崩溃. -
c#检测文本文件编码的方法
2020-09-02 16:56:45主要介绍了c#检测文本文件编码的方法 -
python自动识别文本编码格式代码
2020-09-18 05:34:21今天小编就为大家分享一篇python自动识别文本编码格式代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
文本文件转换编码
2020-06-06 03:17:03前言 preface 因为编程的原因,经成会遇到字符...通常,我的处理方式就是,对于每一个文件,使用记事本依次另存为另一种编码或者使用Notepad++的编码转换。这里推荐一下Notepad++,编码转换使用还是比较方便的。但是前言 preface
因为编程的原因,经成会遇到字符编码的问题。如开发工具使用的是UTF-8编码(推荐使用),然后需要导入一个从其它地方获取的工程项目,但是这个工程使用了GBK编码方式。这就导致了一个常见的问题——乱码。
虽然这里的代码是不影响,但是中文注释全部都乱码了,这可不好玩了,很影响对于代码的阅读,尤其是那种比较多源文件的项目。通常,我的处理方式就是,对于每一个文件,使用记事本依次另存为另一种编码或者使用Notepad++的编码转换。这里推荐一下Notepad++,编码转换使用还是比较方便的。但是一个一个的转换,这都是重复性的操作,有时候也是挺烦的。所以,就萌生了一个使用代码来解决的想法。虽然是一个看似很简单的问题,但是其实是很考验我们对于基础知识的掌握的。想法 idea
这里对于文本文件要有一个理解,任何文件本质上都是字节文件,只不过文本文件使用了字符集编码。也就是说,打开文件显示的字符并不是文件里面存储的真实字符,文件里面存储的永远只是字节。 大致可以按照下图这样来比较简单理解这个过程,打开文件的过程是一个字符映射的过程。
从字节到符号的过程是解码,从符号到字节的过程是编码。
我们看到的字符是字节经过编码映射,然后机器将特定的字符显示到屏幕上面。例如下面这副图片,以“龙”字符为例说明。
对于不同的编码集,字符"龙"具有不同的编码值,这里编码值指的是编码字节的值。
注意这里这个Unicode编码不是龙字的UTF-8编码,这里有点误导人了,但是我们可以去其它地方查询龙字的UTF-8编码,或者也不用舍近求远,如果你了解这方面的知识的话,直接使用代码输出就行了。演示 demo
这里通过一段代码来演示编解码过程,理解这个话的,基本上就知道上面所说的东西了。
这段代码需要一些关于字符、字节和编码的基础知识。package dragon; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.nio.charset.Charset; public class TestMain { public static void main(String[] args) { int 龙_GBK = 0xC1FA; int 龙_UTF8 = 0xe9be99; ByteArrayOutputStream out = new ByteArrayOutputStream(); out.write((龙_GBK >>> 8) & 0xFF); //依次将GBK编码的龙和UTF-8编码的龙写入输出流,这里由于GBK out.write((龙_GBK >>> 0) & 0xFF); //是双字节编码, 因此只写入低两位即可, out.write((龙_UTF8 >>> 16) & 0xFF); //UTF-8是可变长的编码方式,这里的话 龙 是三字节编码。 out.write((龙_UTF8 >>> 8) & 0xFF); out.write((龙_UTF8 >>> 0) & 0xFF); byte[] data = out.toByteArray(); Charset GBK = Charset.forName("GBK"); Charset UTF_8 = Charset.forName("UTF-8"); System.out.println("不同编码显示同一字符:"); System.out.println("使用GBK编码表示的汉字: 龙--->" + new String(data, 0, 2, GBK)); System.out.println("使用UTF-8编码表示的汉字:龙--->" + new String(data, 2, 3, UTF_8)); System.out.println("同一字符编码为不同字符集表示:"); System.out.println("龙 使用GBK编码表示:" + new BigInteger(1, "龙".getBytes(GBK)).toString(16)); System.out.println("龙 使用UTF-8编码表示:" + new BigInteger(1, "龙".getBytes(UTF_8)).toString(16)); } }
运行结果
小结 brief summary
这个结果是不是很有趣呢!
0xc1fa(字节)——>GBK解码——>龙(字符)
龙(字符)——>UTF-8编码——>0xe9be99(字节)一个很自然的想法是,如果把上面这两个过程合起来,不就可以完成不同字符集编码的转换了吗?
当然了,注意前提是需要转换的部分的字符在两个编码集中都是存在的。毕竟你是无法把一个字符集中不存在的字符映射过去。通过上面的演示可以看出来,想要实现编码的转换,就是先将字节解码(本来的编码方式)为符号,再编码(希望的编码)为字节。
即:字节——解码——字符——编码——字节。
注意解码和编码对应的字符集不同,所以原始字节和最终生成的字节是不同的。
这里画的图是从UTF-8到GBK的转换,当然了,也可以反过来的。实现 implement
测试文件 test file
首先提供这样的两个文件,因为我的window的cmd使用是默认的编码,应该是GBK,但是我的这个两个文件都是UTF-8编码的,所以,这里打开是乱码。你也不知道里面写的是啥了。
最终代码 final code
package dragon; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Objects; import java.util.stream.Stream; /** * 编码转换 * UTF_8 * GBK * */ public class EncodeTranslate { private File[] files; //需要转码的文件名字符串 private File desDir; //转码后存放的文件目录 private Charset srcCharset; //文件当前编码 private Charset desCharset; //文件目标编码 /** * @param path 目标文件的路径 * @Param desPath 目的文件的存放路径 * @param type 目标文件的类型 * @param srcEncode 目标文件的编码 * @param desEncode 目的文件的编码 * * */ public EncodeTranslate(String path, String desPath, String type, String srcEncode, String desEncode) throws FileNotFoundException { File dirFile = new File(path); if (!dirFile.exists()) { throw new FileNotFoundException("文件路径不存在:" + path); } this.files = dirFile.listFiles((dir, name)->name.contains(type)); if (this.files.length == 0) { throw new FileNotFoundException("文件路径下不存在相关类型的文件:" + path + "->" + type); } desDir = new File(desPath); if (!desDir.exists()) { //目标文件夹不存在,就创建 if (!desDir.mkdirs()) { //目标文件夹创建失败,路径冲突 throw new FileNotFoundException("无法创建目标路径:" + desPath); } } else { if (!desDir.isDirectory()) { throw new FileNotFoundException("目标路径不是文件夹"); } } this.srcCharset = Charset.forName(srcEncode); this.desCharset = Charset.forName(desEncode); } /** * java 8 的 Stream 的简单应用 * */ public void encodeTranslate() { Stream.of(files).forEach(this::translate); } /** * 把需要转码文件的中字符串按行读取出来,然后对其使用它本身的字符集解码成字节数组, * 再对字节数组按照需要的字符集编码成字符串,然后写入目的文件中。 * */ public void translate(File file) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), srcCharset))) { String fileName = file.getName(); File newFile = new File(desDir, fileName); try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), desCharset))) { String line = null; while (Objects.nonNull(line = reader.readLine())) { byte[] data = line.getBytes(desCharset); // 完成转码最为关键的两步 String newLine = new String(data, desCharset); writer.write(newLine); writer.newLine(); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } package dragon; import java.io.FileNotFoundException; public class Main { public static void main(String[] args) throws FileNotFoundException { if (args.length != 5) { System.out.println("请正确输入各个参数!"); return ; } String path = args[0]; String desPath = args[1]; String type = args[2]; String srcEncode = args[3]; String desEncode = args[4]; // 直接抛出异常,不做处理! EncodeTranslate encodeTranslate = new EncodeTranslate(path, desPath, type, srcEncode, desEncode); encodeTranslate.encodeTranslate(); System.out.println("File Encode Translate Success!"); } }
简要说明
这里无论是读取还是写入都必须指定编码集合,否则是会使用系统默认的编码集,那样也是会出现问题的,因此建议对于任何的文本文件读取和写入都应该显示的指定编码集,以杜绝因此导致的问题。
例如:我最开始没有指定写入文件时的编码集,因为IDE使用的是UTF-8,但是我写入的是GBK编码的内容(我这里只是测试 UTF-8 转 GBK),导致打开文件仍然是乱码。这是一个需要注意的地方。!
//使用指定的编码集读取文件 BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), srcCharset)) //使用指定的编码集写入文件 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), desCharset))
测试输入 test input
这里我就不在cmd里面测试了,我直接使用IDE来测试了,注意下面的五个输入参数,以空格来分隔。
或者你也可以在cmd里面使用,也挺方便的。
测试结果 test result
测试输出信息
测试输出文件
测试输出文件是否转换成功
这里只选取Test1.java来测试即可 。
总结 summary
自己动手实现想法的过程中,也学到了不少东西,因为编码的过程中会遇到一些问题,可能某些概念掌握的不清楚,或者自认为掌握了,实现起来的时候,才会发现,其实不是自己想的那么回事,哈哈!
这是我最开始认为的实现方式,我还沾沾自喜呢。我以为我先按照srcCharset的编码方式解码,再将其按照desCharset的编码方式编码就行了。当时如果你理解上面的话,就会发现这个根本就是不对的嘛! 结果是得到了,完全的乱码文件了,使用notepad++怎么转换也不行了。(当然了,如果再反过来使用代码,也许还有救吧!)
byte[] data = line.getBytes(srcCharset); // 完成转码最为关键的两步 String newLine = new String(data, desCharset);
后来我反应过来了(思索了一会儿),只需要
byte[] data = line.getBytes(desCharset);
这样即可,把字符直接转成desCharset编码即可。并且对于这个字符、编码、字节的概念理解又多了一点,这才是写这篇博客最大的收获吧!我以前一直对这个编码集和字节的关系感到很好奇,当我开始学习Java的IO流的时候,乱码伴随了我好久,例如一开始遇到:UTF-8 BOM 问题时,网上有人回答的是无法解决,我当时还是相信的了(可见错误的答案对人的误解),当时还是坚持去查找,最后发现了这个BOM这个关键字,也就解决了开头的那个文件内容输出开头的那个 ? 问题。编码转换本身是包含很多细枝末节的知识的,就算是现在的我也只是了解到了一些皮毛的知识,这些暂时是够用了,但是还是需要继续学习才行。
随便提一下,这里我主要使用的InputStreamReader
和OutputStreamWriter
正好是我刚开始解决编码,学会使用的两个类,哈哈!这也不算是巧合吧,应该说是一种积累!附 PS
这个程序还可以继续完善,我这里没有涉及文件夹嵌套,例如一个目录里面含有多个文件夹,每个文件夹还含有需要转换的文件。对于通常的项目工程来说,很多的包是必备的,所以对于这种类型的转换直接使用上面的代码是不行的。上面的代码只是一个简单的技术实现,如果想要适应更复杂的情况,还需要继续完善,例如加一个递归就更完美了。有时间的话,也许会补上吧!
-
获取文本文件编码
2013-06-24 00:18:09描述:此工具是用来获取某个目录下的文本文件编码.它依赖于java,在命令下运行.所以运行前必须安装java,配置java环境可以使用path变量,也可以到FileEncoding文件里面配也可以.这工具是基于cpdetector项目,它检查文件的... -
文本文件编码与格式转换
2020-03-13 21:04:33根本原因是你使用的编写文件的工具使用的编码规则和另外一个打开该文件的工具的编码规则不一样,打个比喻,就像搞地下活动的时候,加密和解密用的密码本不一样,自然解密出来的意思就不一样了。 我们简单的普及一下... -
编码转换 文本网页编码批量转换工具 v1.5
2020-10-18 03:35:33文本网页编码批量转换工具是网页文件、文本文件编码批量转换的工具,可以批量将文本类文件批量转换为utf-8 ansi(gb2312) unicode等编码。文本网页编码批量转换工具 v1.5更新内容:新版新 -
windows设置新建文本文档默认编码UTF-8
2018-07-01 15:03:00打开记事本新建一个空白的文本文档,不输入任何文字,然后保存此文档,在“另存为”对话框中将编码由默认的 ANSI 修改为 Unicode 或 UTF-8,接着为文件取名,在此假设将新文档命名为 UNICODE.TXT。 2. 将 utf-8.txt... -
易语言-判断文本编码是否为UTF-8格式
2021-06-25 18:13:46易语言-判断文本编码是否为UTF-8格式 -
基于哈夫曼编码的文本文件压缩与解压缩.zip
2021-07-02 13:21:52哈夫曼编码进行文本压缩 -
算术编码:使用算术编码压缩文本的程序。-matlab开发
2021-05-31 04:52:23AC 用于文本压缩,代码是由 Witten Neal 和 Cleary “AC for DATA COMPRESSION”编写的 C 转换而来 -
基于哈夫曼编码的文本文件压缩与解压缩
2017-10-30 12:01:40基于哈夫曼编码的文本文件压缩与解压缩,使用c语言,实际只是编码解码,不应该称为解压缩,因为编码后文件会更大 -
Huffman-Encoding:一种用于压缩大文本文件的自适应霍夫曼编码的实现
2021-07-12 14:27:22霍夫曼编码 一种用于压缩大文本文件的自适应霍夫曼编码的实现 -
java使用jchardet检测文本文件(字节流)的编码方式
2019-03-28 01:45:27NULL 博文链接:https://zhifeiji512.iteye.com/blog/1221068 -
java判断文本文件编码格式
2019-08-06 09:32:00上篇文章需要读取当前java或者配置文件的编码格式,这里主要支持UTF-8、GBK、UTF-16、Unicode等 ... * @return 文件编码格式 * @throws Exception */ public static String codeString(File fileName) thro... -
java实现获取文本文件的字符编码
2021-02-12 17:27:032、Windows操作系统下,文本文件的默认编码为ANSI,对中文Windows来说即为GBK。例如我们使用记事本程序新建一个文本文档,其默认字符编码即为ANSI。3、Text文本文档有四种编码选项:ANSI、Unicode(含Unicode Big ... -
文本文件的编码
2019-05-21 10:04:01文本文件就是字节序列,可以是任意编码的字节序列。 gbk编码中文占2个字节,英文占1个字节 utf-8 中文占3个字节,英文占1个字节 Java是双字节编码utf-16be, 中文占用2字节,英文占用2字节 public class EncodeDemo...