Давняя проблема с кодировками...
Есть два критичных вопроса (один критичнее другого
) :
1) Возможно ли написать функцию, которая будет возвращать тип кодировки указанной строки?
К примеру, функция будет именоваться так: _StringGetEncoding(), и возвращать будет в соответствии с кодировкой: ANSI, Unicode, UTF-8, UTF-8 with signature.
2) Как перекодировать строку в
UTF-8 with signature кодировку? это нужно для обработки текста разных кодировок, я так понял это единственная кодировка которая справляется с текстом на многих языках.
Дело в том, что мне нужно пис
ать в лог файл, этот лог будет содержать данные, взяты с сети (названия ссылок, заголовок страниц и т.п), но при этом эти данные должны отображаться в моём GUI, для этого я использую функцию
_UTF8ToUnicode (см. в примере далее), но когдя я пишу в файл в режиме UTF-8 with signature (
FileOpen("log.txt", 129)), то данные пишутся некорректно, т.е если строка на русском, то либо пишет всё что
до русских символов + русские символы (и дальше не пишет
), либо вообще не пишет русские символы, точно как показано в примере ниже:
Код:
;Запишем сначала в файл, чтобы получить строку в кодировке Unicode (строка может быть и в этой кодировке, но проверить я не могу(?))
$hFile = FileOpen(@ScriptDir & "\temp.txt", 34)
FileWrite($hFile, "Some [Тест.txt] and more test" & @CRLF)
FileClose($hFile)
$Line = FileRead(@ScriptDir & "\temp.txt")
FileDelete(@ScriptDir & "\temp.txt")
;Теперь пишем в лог (с UTF-8 with signature кодировкой), текст с русскими символами вообще не пишется :(
$Log_File = @ScriptDir & "\Log.txt"
WriteLog($Log_File, _Utf8ToUnicode($Line))
ShellExecute($Log_File)
Func WriteLog($sFile, $Line)
Local $hFile = FileOpen($sFile, 129)
FileWrite($hFile, $Line)
FileClose($hFile)
EndFunc
Func _Utf8ToUnicode($Utf8String)
Local $BufferSize = StringLen($Utf8String) * 2
Local $Buffer = DllStructCreate("byte[" & $BufferSize & "]")
Local $Return = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", _
"int", 65001, _
"int", 0, _
"str", $Utf8String, _
"int", StringLen($Utf8String), _
"ptr", DllStructGetPtr($Buffer), _
"int", $BufferSize)
Local $UnicodeBinary = DllStructGetData($Buffer, 1)
Local $UnicodeHex1 = StringReplace($UnicodeBinary, "0x", "")
Local $UnicodeString, $UnicodeHex2, $UnicodeHex3
For $i = 1 To StringLen($UnicodeHex1) Step 4
$UnicodeHex2 = StringMid($UnicodeHex1, $i, 4)
$UnicodeHex3 = StringMid($UnicodeHex2, 3, 2) & StringMid($UnicodeHex2, 1, 2)
$UnicodeString &= ChrW(Dec($UnicodeHex3))
Next
$Buffer = 0
Return $UnicodeString
EndFunc
Это не идеальный пример моей проблеме, в этом примере
можно сделать так чтобы всё записывалось как надо, но бывают и посложнее ситуации, с другими кодировками и на других языках.
P.S
Я верю что если найдётся решение для двух этих вопросов, то все мои (и не только) проблемы связанные с кодировками будут решены.