Powerbuilder:UTF-8的导入文件(将UTF-8转换为ANSI)

Powerbuilder:UTF-8的导入文件(将UTF-8转换为ANSI),utf-8,powerbuilder,datawindow,Utf 8,Powerbuilder,Datawindow,我的Powerbuilder版本是6.5,无法使用更高版本,因为这是我支持的版本 我的问题是,在执行dw_1.ImportFile(文件)时,第一行和第一列有一个有趣的字符串,如下所示:  直到我尝试打开文件并将其保存到一个新的文本文件并尝试导入该新文件时,我才明白这一点 我的结论是,发生这种情况是因为文件是UTF-8(如NOTEPAD++所示),而新文件是Ansi。我试图导入的文件是由第三方自动提供的,我的用户不想为此做额外的工作 如何在powerbuilder中将此文件强制转换为AN

我的Powerbuilder版本是6.5,无法使用更高版本,因为这是我支持的版本

我的问题是,在执行dw_1.ImportFile(文件)时,第一行和第一列有一个有趣的字符串,如下所示:


直到我尝试打开文件并将其保存到一个新的文本文件并尝试导入该新文件时,我才明白这一点

我的结论是,发生这种情况是因为文件是UTF-8(如NOTEPAD++所示),而新文件是Ansi。我试图导入的文件是由第三方自动提供的,我的用户不想为此做额外的工作


如何在powerbuilder中将此文件强制转换为ANSI。如果没有,我可能需要执行命令提示符转换,有什么想法吗?

奇怪的
字符是(可选)utf-8 BOM,它告诉编辑器文件是utf-8编码的(因为除非我们在代码127上方遇到转义字符,否则很难知道它)。您不能将其删除,因为如果您的文件包含127以上的任何字符(重音符号或任何特殊字符),则显示的数据中仍会有垃圾(例如:
->
Ã
->
字符),其中特殊字符将从2个垃圾字符变为4个垃圾字符

我最近需要将一些utf-8编码的字符串转换为“ansi”Windows1252编码。在PB10+版本中,utf-8和ansi之间的重新编码非常简单

b = blob(s, encodingutf8!)
s2 = string(b, encodingansi!)
但是
string()
blob()
在PB第10版之前不支持编码规范

您可以自己读取文件,跳过BOM表,让Windows通过
MultiByteToWideChar()
+
WideCharToMultiByte()
转换字符串编码,并使用
ImportString()
将转换后的字符串加载到DW中

获取文件内容的概念证明(使用此读取方法,文件不能大于2GB):

utf8_to_ansi()
是一个globlal函数,它是为PB9编写的,但它应该与PB6.5的工作原理相同:

global type utf8_to_ansi from function_object
end type

type prototypes
function ulong MultiByteToWideChar(ulong CodePage, ulong dwflags, ref string lpmultibytestr, ulong cchmultibyte, ref blob lpwidecharstr, ulong cchwidechar) library "kernel32.dll"
function ulong WideCharToMultiByte(ulong CodePage, ulong dwFlags, ref blob lpWideCharStr, ulong cchWideChar, ref string lpMultiByteStr, ulong cbMultiByte, ref string lpUsedDefaultChar, ref boolean lpUsedDefaultChar) library "kernel32.dll"
end prototypes

forward prototypes
global function string utf8_to_ansi (string as_utf8)
end prototypes

global function string utf8_to_ansi (string as_utf8);

//convert utf-8 -> ansi
//use a wide-char native string as pivot

constant ulong CP_ACP = 0
constant ulong CP_UTF8 = 65001

string ls_wide, ls_ansi, ls_null
blob lbl_wide
ulong ul_len
boolean lb_flag

setnull(ls_null)
lb_flag = false

//get utf-8 string length converted as wide-char
setnull(lbl_wide)
ul_len = multibytetowidechar(CP_UTF8, 0, as_utf8, -1, lbl_wide, 0)
//allocate buffer to let windows write into
ls_wide = space(ul_len * 2)
lbl_wide = blob(ls_wide)
//convert utf-8 -> wide char
ul_len = multibytetowidechar(CP_UTF8, 0, as_utf8, -1, lbl_wide, ul_len)
//get the final ansi string length
setnull(ls_ansi)
ul_len = widechartomultibyte(CP_ACP, 0, lbl_wide, -1, ls_ansi, 0, ls_null, lb_flag)
//allocate buffer to let windows write into
ls_ansi = space(ul_len)
//convert wide-char -> ansi
ul_len = widechartomultibyte(CP_ACP, 0, lbl_wide, -1, ls_ansi, ul_len, ls_null, lb_flag)

return ls_ansi
end function

看起来像UTF-8字节顺序标记,Unicode零宽度不间断空格字符。您可以删除这三个字节。(顺便说一句,“ANSI”对于包括Windows-1252在内的一系列特定于Microsoft的8位编码来说是一个误称。)@KeithThompson:如果文件包含一些经过编码的重音字符或扩展字符,仅删除utf-8 BOM(实际上是奇怪的字符串前缀)不会产生正确的结果。关于ANSI错误命名的权利,但是使用PowerBuilder
编码ANSI
是本机1252编码文件的常量(除了
encodingUtf8!
encodingutf16le
encodingUtf16be
)对不起,如果不是ANSI,它应该被称为什么。无论如何,我将尝试返回。我正在向dw导入35000多行(以制表符分隔的列)。在这种情况下,我还可以使用ImportString吗?实际上,我正在将这些行存储到SQL中的临时表中。然后执行一个循环来解析每一行、读取并将适当的数据插入主表。如果我可以确定这些字符,我可以删除它们并插入正确的值吗?我们是否有一个已知的、固定的、可能的字符/字符串,我应该研究它?我本来打算改做regex的。嗨,Seki,这工作完美无瑕,一件事。。我只在6.5版本中使用了ImportString(ls_文件)。添加“text!”将导致我的版本出现语法错误。非常感谢你。再一次你好,seki,另一件事。在我的场景中,我如何知道文件是否不是UTF。有几个第三方向我们发送制表符分隔的文件,但并非所有文件都是UTF-8。现在,当我尝试使用ANSI编码时,它似乎从第一行中删除了字符。谢谢,我阅读了文件并检查第一个字符串是否在ASCII ASC(字符串)>0和ASC(字符串)<126的范围内。又来了。
global type utf8_to_ansi from function_object
end type

type prototypes
function ulong MultiByteToWideChar(ulong CodePage, ulong dwflags, ref string lpmultibytestr, ulong cchmultibyte, ref blob lpwidecharstr, ulong cchwidechar) library "kernel32.dll"
function ulong WideCharToMultiByte(ulong CodePage, ulong dwFlags, ref blob lpWideCharStr, ulong cchWideChar, ref string lpMultiByteStr, ulong cbMultiByte, ref string lpUsedDefaultChar, ref boolean lpUsedDefaultChar) library "kernel32.dll"
end prototypes

forward prototypes
global function string utf8_to_ansi (string as_utf8)
end prototypes

global function string utf8_to_ansi (string as_utf8);

//convert utf-8 -> ansi
//use a wide-char native string as pivot

constant ulong CP_ACP = 0
constant ulong CP_UTF8 = 65001

string ls_wide, ls_ansi, ls_null
blob lbl_wide
ulong ul_len
boolean lb_flag

setnull(ls_null)
lb_flag = false

//get utf-8 string length converted as wide-char
setnull(lbl_wide)
ul_len = multibytetowidechar(CP_UTF8, 0, as_utf8, -1, lbl_wide, 0)
//allocate buffer to let windows write into
ls_wide = space(ul_len * 2)
lbl_wide = blob(ls_wide)
//convert utf-8 -> wide char
ul_len = multibytetowidechar(CP_UTF8, 0, as_utf8, -1, lbl_wide, ul_len)
//get the final ansi string length
setnull(ls_ansi)
ul_len = widechartomultibyte(CP_ACP, 0, lbl_wide, -1, ls_ansi, 0, ls_null, lb_flag)
//allocate buffer to let windows write into
ls_ansi = space(ul_len)
//convert wide-char -> ansi
ul_len = widechartomultibyte(CP_ACP, 0, lbl_wide, -1, ls_ansi, ul_len, ls_null, lb_flag)

return ls_ansi
end function