| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3719 人关注过本帖
标题:再次探讨判断文本文件编码格式的问题
只看楼主 加入收藏
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:989
专家分:4966
注 册:2013-2-16
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:10 
再次探讨判断文本文件编码格式的问题
背景介绍:
1、读入一段文本,由于VFP对ANSI支持较好,那么读入前,我们需要有一个机制,预先判断文本文件的编码格式,
如果是ANSI编码,则直接把文件读入到界面;否则,如果不是ANSI编码,则弹出警告框,提示用户先转换编码格式再读入。
2、本人已经看过十豆三老师的文章,比如这个:http://blog.

问题:
目前找到的办法(指VFP下的办法,也包括十豆三老师的办法),都存在一个缺陷,即部分文件格式,会误判断。
比如十豆三老师 判断编码格式的代码:
程序代码:
*--文本文件的编码格式手动查看方法:
lcFileName='C:/A.txt'    &&文本文件名
lcStr=Filetostr(lcFileName)
lcStrType=Createbinary(Substr(lcStr,1,2))
Do Case
    Case lcStrType=0hEFBB    &&VFP6.0不支持此种方式,此实列是在VFP9.0+SP2下测试的。
        lcCode='UTF-8'
    Case lcStrType=0hFFFE
        lcCode='Unicode'
    Case lcStrType=0hFEFF
        lcCode='Unicode big endian'
    Otherwise
        lcCode='ANSI'
Endcase
?'此文本的编码格式为:',lcCode


举例说明:
附上2个附件,这些附件,明明不是ANSI格式,但是用以上方法,都判断失误。
所以,各位有没有办法能准确的判断?(用VFP代码实现)

目前我自己采用的办法是:
写了一个DLL,这个DLL倒是可以准确判断文件的编码格式,然后,我在VFP中,调用这个DLL。
有点绕,但是好在也能解决问题。
问题是解决了,但是想探讨一下用纯VFP手段有没有办法做到?
Utf8WithoutBom示例.rar (3 MB)
Unicode示例.rar (228 Bytes)
搜索更多相关主题的帖子: 格式 判断 编码 文本文件 办法 
2020-06-18 11:00
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9841
专家分:27213
注 册:2012-2-5
收藏
得分:0 
压缩文件版本太高。不能解压缩

坚守VFP最后的阵地
2020-06-18 11:25
wengjl
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:109
帖 子:2214
专家分:3882
注 册:2007-4-27
收藏
得分:0 

只求每天有一丁点儿的进步就可以了
2020-06-18 12:24
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:5 
《Windows核心编程》(第五版) 摘录一段相关的内容:

    对于需要打开文本文件并进行处理的大多数应用程序(比如编译器)而言,如果应用程序能够在打开一个文件之后分辨出此文件中包含的是ANSI字符还是Unicode字符,将是多么惬意而方便啊!IsTextUnicode函数有助于进行这种分辨,该函数由 AdvApi32.dll 导出并在 WinBase.h 中声明:
   
    BOOL IsTextUnicode(CONST PVOID pvBuffer, int cb, PINT pResult);

    文本文件的问题在于,它们的内容没有任何硬性的、可供快速判断的规则。所以,要判断文件中包含的是ANSI字符还是Unicode字符,就显显得相当困难。IsTextUnicode函数使用一系列统计性和确定性方法来猜测缓冲区中的内容。由于这种方法并不精确,因此IsTextUnicode函数可能会返回错误的结果。

[此贴子已经被作者于2020-6-18 15:21编辑过]

2020-06-18 15:20
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:989
专家分:4966
注 册:2013-2-16
收藏
得分:0 
回复 2楼 sdta
Unicode示例.7z (245 Bytes)
Utf8WithoutBom示例.7z (2.66 MB)
  重新用7Z 格式压缩了.
2020-06-18 16:11
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:10 
可以试试按编码规则来判断
如判断是否UTF-8编码文本:
cFileName = "C:\TEMP\Unicode示例\娇妻如云2.txt"
? IsUTF8(LEFT(FILETOSTR(cFileName),1000), 1000)
RETURN

FUNCTION IsUTF8(s, nLen)  
    LOCAL i, bUTF8, ch
    nLen = MIN(LEN(s), nLen)
    bUTF8 = .T.
    i = 1
    DO WHILE i <= nLen
        ch = ASC(SUBSTR(s,i,1))
        DO CASE
        CASE ch < 0x80  && (0b10000000) 值小于0x80的为ASCII字符   
            i = i + 1
        CASE ch < 0xC0  && (0b11000000) 值介于0x80与0xC0之间的为无效UTF-8字符   
            bUTF8 = .F.
            EXIT
        CASE ch < 0xE0  && (0b11100000) 此范围内为2字节UTF-8字符   
            IF i >= nLen
                EXIT
            ENDIF
            IF BITAND(ASC(SUBSTR(s,i+1,1)),0xC0) != 0x80
                bUTF8 = .F.
                EXIT
            ENDIF
            i = i + 2
        CASE ch < 0xF0  && (0b11110000) 此范围内为3字节UTF-8字符   
            IF i >= (nLen-1)
                EXIT
            ENDIF
            IF (BITAND(ASC(SUBSTR(s,i+1,1)),0xC0) != 0x80) OR (BITAND(ASC(SUBSTR(s,i+2,1)),0xC0) != 0x80)
                bUTF8 = .F.
                EXIT
            ENDIF
            i = i + 3
        OTHERWISE
            bUTF8 = .F.
            EXIT
        ENDCASE
    ENDDO
    RETURN bUTF8
ENDFUNC
2020-06-19 10:21
xuminxz
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:41
帖 子:766
专家分:2517
注 册:2011-5-8
收藏
得分:0 
将文件读入到二进制备注字段试试。

dBase有人接盘了。
2020-06-19 10:26
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
以下是引用厨师王德榜在2020-6-18 11:00:19的发言:
*--文本文件的编码格式手动查看方法:
lcFileName='C:/A.txt'    &&文本文件名
lcStr=Filetostr(lcFileName)
lcStrType=Createbinary(Substr(lcStr,1,2))
Do Case
    Case lcStrType=0hEFBB    &&VFP6.0不支持此种方式,此实列是在VFP9.0+SP2下测试的。
        lcCode='UTF-8'
    Case lcStrType=0hFFFE
        lcCode='Unicode'
    Case lcStrType=0hFEFF
        lcCode='Unicode big endian'
    Otherwise
        lcCode='ANSI'
Endcase
?'此文本的编码格式为:',lcCode

这段代码对带有BOM标志的文本文件有效
然而BOM不是必需的,而且也不推荐,BOM会带来兼容性问题
2020-06-19 11:15
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:989
专家分:4966
注 册:2013-2-16
收藏
得分:0 
回复 8楼 吹水佬
是的,同意你的观点.如果是我自己的程序生成的TXT,一定不让他有各种格式.
但是我们收集客户上传的TXT,他们生成的格式各种都有,
我们没办法去要求客户一定用或者不用哪种格式,
甚至,一般的用户连什么叫ANSI,什么叫UTF-8,什么叫Unicode都没有听说过,
这样就更谈不上去要求他了,所以,只能是我们适应他,尽可能的去解读他们发来的格式.

这个问题我通过调用第3方的DLL已经解决,本帖只是探讨在VFP这个框架下:
判断多数文件都没有问题,就是不带BOM的UTF8,和部分Unicode文档无法判定.
2020-06-19 12:05
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1730
专家分:3324
注 册:2012-2-29
收藏
得分:0 
学习,谢谢!
2020-06-19 12:35
快速回复:再次探讨判断文本文件编码格式的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026095 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved