读写文本文件时出现了乱码,找到了ADODB.Stream,可以指定字符集读取文本

Function ReadUTF()

    Filename = "F:\vba\2018 - new\2018-10-29 cad打桩\3 - cad打桩\代码\1.txt"

    With CreateObject("ADODB.Stream")
.Type = '读取文本文件
.Mode = '读写
.Open
.LoadFromFile Filename
' .Charset = "UTF-8"
' .Charset = "Unicode"
.Charset = "GB2312" 'GB2312 = ANSI
.Position =
ReadUTF = .ReadText
.Close
End With Debug.Print ReadUTF End Function

发现ANSI竟然就是GB2312,不过百度一下才发现不仅仅是简单的等于GB2312,有个网址讲的非常的到位

http://club.excelhome.net/thread-998747-1-1.html
三、ANSI编码(ISO8859、GB2312、Big5、JIS等等)

      在二楼的介绍中,我们讲解了计算机是如何显示键盘字符的(通常我们称为ASCII字符)。那么,我们伟大的中华民族的汉字多达十万个,常用的也有两三万,这又该如何显示呢?ASCII标准编码只有0~127,
扩展编码128~255,完全放不下这么多汉字嘛。 莫非,电脑发明的时候,就是给英语国家用的? 是的,你猜对了,最早电脑发明的时候,完全没有考虑这个世界上还会有其他的民族也会用到电脑,而这些民族的字符集会多达数万!有人问了,为什么当年的
科学家不考虑地球的其他民族呢?俺猜想,这与当年存储器的容纳能力有关,如果采用一个字节存储英文字符,完全足够了。如果考虑其他民族,就要用两个甚至更多的存储空间来存放英文字符(以便兼容多民族字符),
而为了这种兼容需要多支付的存储空间,其代价是当年的技术所不能承受的。 后来,随着技术的进步,单位存储空间的费用已经降低到了一个可以接受的地步,为地球多民族的字符集做编码,终于变为了可能。ANSI(美国国家标准学会)在这样的背景下,出台了一系列字符集,这些字符
集再加上其他国家为本国语言所设计的早期字符集,统称为ANSI编码。 所以,提到ANSI字符集,你一定要知道,这是一个由许多不同国家的字符集所构成的一个字符集集合的统称,而不是一个特定的字符集。同一个操作系统在不同的国家的ANSI编码,就是这个国家的字符集编码。
例如,欧洲国家用ISO8859(包括15个不同国家的子集)、中国大陆用GB2312、台湾用Big5、日本用JIS等等 ANSI的子集,在不同的操作系统下是不一样的,这取决于操作系统所支持的字符集。例如,同样是简体中文,Win32下的ANSI是GB2312,Windows95是GBK。Windows7是GB18030(完整支持需要安装扩展字体)等 补充内容 (2013-4-27 00:08):
GB2312、GBK、 GB18030等都属于双字节字符集 (DBCS double-byte character set)。 DBCS是亚洲字符集,包括简中、繁中、日、韩。在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节
作为一个双字节编码。

后又发现 position如果设置为0,竟然会有一个乱码出现,但是文件的内容为什么不是从0开始的,而是从2开始的(position即光标的位置,就是设置从第几个字符开始读取文件内容),原来前两个字节用来定义文件的编码方式了,不过也不能简单的说是前两个字节,有些编码方式不是前两个字节

Function checkcode(path)

    Set objstream = CreateObject("adodb.stream")
objstream.Type =
objstream.Mode =
objstream.Open
objstream.Position =
objstream.LoadFromFile path
bintou = objstream.read() If bintou() = &HEF And bintou() = &HBB Then
checkcode = "utf-8" ElseIf bintou() = &HFF And bintou() = &HFE Then
checkcode = "unicode" ElseIf bintou() = And bintou() = Then
checkcode = "gb2312" Else
checkcode = "其他"
End If ' If AscB(MidB(bintou, 1, 1)) = &HEF And AscB(MidB(bintou, 2, 1)) = &HBB Then
' checkcode = "utf-8"
' ElseIf AscB(MidB(bintou, 1, 1)) = &HFF And AscB(MidB(bintou, 2, 1)) = &HFE Then
' checkcode = "unicode"
' Else
' checkcode = "gb2312"
' End If objstream.Close
Set objstream = Nothing End Function
AscB(MidB(bintou, , )) = &HEF

bintou() = &HEF

经过测试,两种方式都是可以的,但是个人更喜欢简洁明了一点的方式
UTF8文件有BOM和No BOM两种,其区别在于BOM多了三个字节(EFBBBF),对比了二进制文件,发现有这个区别,如果是NoBOM的文件就无法通过前两个字节判断是否为UTF-8文件。

对于没有BOM的UTF-8文件,可以通过遍历判断是否为UTF-8编码。遍历方法可以是二进制的移位判断或者是正则。

https://www.w3.org/International/questions/qa-forms-utf-8

例如,当使用Perl时,可用以下的表达式测试页面是否使用了UTF-8编码:

$field =~
m/\A(
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong -byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{} # straight -byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{} # planes -
| [\xF1-\xF3][\x80-\xBF]{} # planes -
| \xF4[\x80-\x8F][\x80-\xBF]{} # plane
)*\z/x; 以上表达式可转换成其他编程语言。这样就能处理各类问题,例如过长的错误编码以及非法的代理使用。$field 属于UTF-8编码时就会顺利返回,否则失败。

关于 BOM 和 NO BOM

http://club.excelhome.net/thread-998747-2-1.html

十、网络文本的传输标准(UTF-)

很多时候,我们不能直接传输Unicode编码的文本字符。因为Unicode编码不是为传输而设计,其编码为硬性规定。对接收方来说,接到了Unicode编码的数据,很难判断这是什么编码格式,会造成识别上的混乱。
为了兼容ASCII字符,并避免遇到\0造成字符串中断,以及解决英文传输体积被填零放大一倍的问题,提出了UTF-8编码规范。UTF-8的每一个字符按规则编码为1~4任一字节组合。中文大部分为为3字节长,部分四字节。 为了避免在文本传输中发生混乱,互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。 此外,在 Unix 世界中使用 UCS-( 或 UCS-) 会导致非常严重的问题。使用这两种编码方式的字符串,可能会包含诸如 字节 "/0" 或 "/" 作 为很多宽字符的组成部 分,
而这样的字节在文件名和其它 C 语言库函数中有特殊的意义。此外,大多数 Unix 工具都被设计用来处理 ASCII 文件的,不进行大 幅 度的修改是无法读取 -bit 字符的。
基于这些原因,在文件名、文本文件、环境变量等地方, UCS- ( 或 UCS- ) 不是一种合适的 Unicode 外部编码。
在 ISO -: 附 录 D 、 RFC3629 以 及 Unicode 4.0 标准的 3.9 节中均有定义的 UTF- 编码方法则不存在上述问题。所以在类 Unix 风格的操作系统中使用UTF-8来应用 Unicode编码。 UTF-8编码字节含义 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符;
如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;
如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示; 因此,对UTF-8编码中的任意字节, 根据第一位,可判断是否为ASCII字符; 根据前二位,可判断该字节是否为一个字符编码的第一个字节;
根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为1),可判断编码是否有错误或数据传输过程中是否有错误。 UTF-8的设计有以下的多字符组串行的特质:
单字节字符的最高有效比特永远为0。
多字节串行中的首个字符组的几个最高有效比特决定了串行的长度。最高有效位为110的是2字节串行,而1110的是三字节串行,如此类推。
多字节串行中其余的字节中的首两个最高有效比特为10。
UTF-8的这些特质,保证了一个字符的字节串行不会包含在另一个字符的字节串行中。这确保了数据接收方可以从任意一个位置来判断字符的起始字节,适用于在文字中搜索字或词。
另一方面,由于其字节串行设计,如果一个疑似为字符串的串行被验证为UTF-8编码,那么我们可以有把握地说它是UTF-8字符串。一段两字节随机串行碰巧为合法的UTF-8而非ASCII的机率为32分1。
对于三字节串行的机率为256分1,对更长的串行的机率就更低了。这样从概率上能避免识别的错误。 UCS和 Unicode标准中对UTF-8的定义稍有不同,因为在UCS中,UTF-8字节序列的最大可能长度为6,以表示所有码值不大于U+7FFFFFFF的 字符;而在Unicode中,UTF-8字节序列的最大可能长度为4,
以表示所有码值不大于U+0010FFFF的字符。(这一差别在本质上与UCS- 和UTF-32之间的相同)。 如何识别文本传输的编码:
最标准的途径是检测文本最开头的几个字节(BOM),
开头字节 Charset/encoding,
EF BB BF UTF-
FF FE UTF-/UCS-, little endian -- Windows标准(低位在前),Unicode编码
FE FF UTF-/UCS-, big endian
FF FE UTF-/UCS-, little endian.
FE FF UTF-/UCS-, big-endian. 如果传输的文本没有Bom,那就需要采用正则或者其他方式来遍历文本,判断编码规范了。 这里有个有趣的现象。如果你打开记事本,输入联通两个字,然后把文件保存成ANSI格式。当你再次打开的时候,会发现文本乱码。
这是因为"联通"的ANSI/GB2312编码是:
c1
aa
cd
a8
恰好符合UTF-8的编码规范,因此造成识别错误。如果你在"联通"之后多输入几个字,其他的字的编码不见得又恰好是110和10开始的字节,这样再次打开时,记事本就不会坚持这是一个utf8编码的文件,
而会用ANSI的方式解读之,这时乱码就不出现了。 对于添加UTF- BOM( 字节串 :0XFF 0XBB 0XBF) 的做法,不被Unicode组织推荐,特别是是不能在 POSIX 系统中采用这种做法。此外,在文件头部添加 UTF- 签名会对很多已有惯例产生妨碍,例如处理一个纯文本程序。 正则表达式判断数据是否为UTF-8编码, 参考 http://www.w3.org/International/questions/qa-forms-utf-8,后面有参考代码 最后,总结一下各种文本编码:
ANSI/GB2312/GBK/GB18030 这些都是区域性编码,没有BOM
UNICODE 目前Windows操作系统使用的内码(低位在前),得到大部分编程语言的支持。标准数据有BOM头。
UTF-/UTF- 通常我们把这个看作传输编码(Unicode的实现方式),用于互联网数据传输。标准数据可能有BOM头。

最后提供一个详细说明 adodb.stream 对象的属性和方法的网址

https://blog.csdn.net/icanlove/article/details/39394701

ADODB.Stream的更多相关文章

  1. asp上传图片提示 ADODB.Stream 错误 '800a0bbc'的解决方法

    asp上传图片提示 ADODB.Stream 错误 '800a0bbc' 有这个提示有很多问题导致.权限是常见一种.这个不多说,还有一个有点怪的就是 windows2008显示系统时间的格式竟然是:2 ...

  2. IE下使用ADODB.Stream实现断点续传

    最近研究了一下IE自带的一些Activex控件,可以比较简单的实现断点续传功能 不过这种方式不推荐,因为安全性较低,而且需要修改客户端注册表,调低ie安全配置 还有就是我比较懒,只打算写个思路和几个关 ...

  3. 解决:ADODB.Stream 错误 '800a0bbc' 写入文件失败

    重装更改目录为e盘后,上传文件出现问题.解决方法: 调用adodb.stream的savetofile方法时发生错误, ADODB.Stream 错误 800a0bbc 写入文件失败.(msxml3. ...

  4. asp adodb.stream读取文件和写文件

    读取文件操作: '------------------------------------------------- '函数名称:ReadTextFile '作用:利用AdoDb.Stream对象来读 ...

  5. ASP 读写文件FSO,adodb.stream

    例如静态化页面的时候 总结:用server.CreateObject("adodb.stream") 来读写比较好,可避免乱码和读取到多余的字符.....不推荐 "scr ...

  6. adodb.stream对象的方法/属性

    Cancel 方法      使用方法如下      Object.Cancel      说明:取消执行挂起的异步 Execute 或 Open 方法的调用.Close   方法      使用方法 ...

  7. ADODB.Stream在进行文件上传时报错

    最近在做web项目,有个控件是上传材料文件和文件夹,本地运行正常,放到服务器上,一直报错:AutoRuntime服务器无法创建..... 解决方法: 1.配置ie浏览器的安全级别 2.修改ie浏览器对 ...

  8. ASP模拟POST请求异步提交数据的方法

    这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...

  9. WinHttp

    using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System. ...

随机推荐

  1. 你不知道的JavaScript--Item34 大白话解说Promise

    去年6月份. ES2015正式公布(也就是ES6.ES6是它的乳名),当中Promise被列为正式规范.作为ES6中最重要的特性之中的一个,我们有必要掌握并理解透彻.本文将由浅到深,解说Promise ...

  2. POJ 1300 Door Man(欧拉通路)

    题目描写叙述: 你是一座大庄园的管家. 庄园有非常多房间,编号为 0.1.2.3..... 你的主人是一个心不在 焉的人,常常沿着走廊任意地把房间的门打开.多年来,你掌握了一个诀窍:沿着一个通道,穿 ...

  3. 【JavaScript】JS读取XML文件并进行搜索

    需求效果 点击链接.当前页面载入xml文件并展示相应内容 通过搜索框.搜索xml文件内节点数据.展示包括内容的节点数据 功能实现 Demo终于实现效果 http://loadxmldemo.coder ...

  4. phonegap运行原理

    用phonegap(现在名为cordova)来开发手机应用,给人的感觉,就是写了一些HTML5的网页,加上javascript,打包安装在手机上,然后就可以运行了,并且还能访问手机的各种功能和硬件,太 ...

  5. Vue相关开源项目库汇总 http://www.opendigg.com/tags/front-vue

    awesome-github-vue 是由OpenDigg整理并维护的Vue相关开源项目库集合.我们会定期同步OpenDigg上的项目到这里,也欢迎各位提交项目给我们. 如果收录的项目有错误,可以通过 ...

  6. luogu 3415 祭坛

    题目大意: 在平面上,有 n 个水晶柱,每个水晶柱可以用一个点表示 如果 4 个水晶柱依次相连可以构成一个四边形,满足其两条对角线分别平行于 x 轴和 y 轴,并且对角线的交点位于四边形内部(不包括边 ...

  7. B1877 [SDOI2009]晨跑 费用流

    其实之前写过一个板子,但是一点印象都没有,所以今天重写了一下,顺便把这个题当成板子就行了. 其实费用流就是把bfs换成spfa,但是中间有一个原则,就是费用优先,在费用(就是c)上跑spfa,顺便求出 ...

  8. JSP-Runoob:Cookie 处理

    ylbtech-JSP-Runoob:Cookie 处理 1.返回顶部 1. JSP Cookie 处理 Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JS ...

  9. Speed Limit

    http://poj.org/problem?id=2017 #include<stdio.h> int main() { int n,mile,hour; ) { ,h = ; whil ...

  10. [Swift通天遁地]二、表格表单-(16)在表单行内嵌入日期和时间拾取器

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...