Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Problem mit FileRead (FileEncoding??)



  • Please log in to reply
12 replies to this topic
Sheik
  • Members
  • 25 posts
  • Last active: Jan 09 2014 07:34 AM
  • Joined: 06 Nov 2012

Hallo!

 

Ich habe ein Problem, bestimmte Dateien mit FileRead zu lesen.

Laut Notepad++ sind die Dateien im "UCS-2 Little Endian"-Format und nach jedem Zeichen kommt ein NUL-Zeichen. Die Datei selbst ist eine .xml-Datei.

 

file_encoding.jpg

 

 

Ich habe schon verschiedene Versuche gestartet, den Dateiinhalt zu lesen:

 

 

File := FileOpen(Datei, "r")
Encoding := File.Encoding
MsgBox % File.Encoding ; Ausgabe: UTF-16
MsgBox % IsObject(File) ; Ausgabe: 1
MsgBox % File.ReadLine() ; Ausgabe: nichts
MsgBox % File.ReadLine(1) ; Ausgabe: nichts
MsgBox % File.Position ; Ausgabe: 131072
MsgBox % File.length ; Ausgabe: 25163184
File.Close()


FileRead, File, *CP1200 %Datei%
MsgBox % ErrorLevel ; Ausgabe: 1
MsgBox % File ; Ausgabe: nichts


FileEncoding, %Encoding%
FileRead, File, %Datei%
MsgBox % ErrorLevel ; Ausgabe: 0
MsgBox % File ; Ausgabe: nichts

MsgBox % A_IsUnicode ? "Unicode" : "ANSI" ; Ausgabe: Unicode

 

Was mache ich falsch? sad.png

 

Danke für Eure Hilfe!



jNizM
  • Members
  • 928 posts
  • Last active: Jan 12 2018 09:23 AM
  • Joined: 01 Aug 2012

http://www.autohotke...s-2-big-endian/


[AHK] 1.1.27.04 x64 Unicode | [WIN] 10 Pro (Version 1709)
My GitHub Profile | Donations are appreciated if I could help you

Sheik
  • Members
  • 25 posts
  • Last active: Jan 09 2014 07:34 AM
  • Joined: 06 Nov 2012

Danke für den Link, leider klappt keines der beiden Beispiele. Meine Ausgabe bleibt immer noch leer.



nnnik
  • Members
  • 1625 posts
  • Last active: Jan 24 2019 02:19 PM
  • Joined: 28 Jul 2012

Versuch es einfach über File.ReadNum()

Dann kannst du die entsprechenden stellen überspringen oder du Arbeitest direkt mit NumGet.

File := FileOpen(Datei, "r")
len:=File.RawRead(var,File.length)
Loop, len//4
s.=chr(numget(var,4*(A_Index-1),"UInt")) 
Msgbox % s

Visit the new forum ahkscript.org.

http://ahkscript.org


Sheik
  • Members
  • 25 posts
  • Last active: Jan 09 2014 07:34 AM
  • Joined: 06 Nov 2012

Hallo nnnik,

 

leider bleibt auch mit deinem Vorschlag die Variable 's' leer.

In 'var' sind nur lauter chinesische Zeichen?!

Vielleicht sonst noch Ideen? shy.png

Was hat das überhaupt für einen Nutzen, Dateien so zu kodieren, wie in meinem Fall? Weiß das jemand?

 

inhalt_von_var.jpg



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Im Dateiheader steht:  encoding=utf-32 !


Prefer ahkscript.org for the time being.


hd0202
  • Members
  • 709 posts
  • Last active: Feb 14 2016 08:05 PM
  • Joined: 13 Aug 2006

nnnik's Ansatz ist ja schon ganz gut, aber mit Flüchtigkeits-Fehlern behaftet. Hier meine korrigierte Version:

    File := FileOpen(Datei, "r")
    len:=File.RawRead(var,File.length)
    Loop, % len//2  ; % fehlte, 4 statt 2, jedes 2. byte
    s.=chr(numget(var,2*(A_Index-1)+1,"UChar"))  ; 4 statt 2, ab Stelle 1 statt Stelle 2, UInt statt UChar
    Msgbox % s

Hubert



Sheik
  • Members
  • 25 posts
  • Last active: Jan 09 2014 07:34 AM
  • Joined: 06 Nov 2012

Danke für eure Hilfe, leider klappts immer noch nicht. Entweder steh ich grad furchtbar aufm Schlauch oder ich bin zu dumm dafür.

 

Ich hab euch jetzt mal einen kleinen Teil einer UCS-2 Little Endian Datei hochgeladen, vielleicht hilft euch das weiter. (Das die XML vom Aufbau her nun nicht mehr korrekt ist, sollte eigentlich keine Rolle spielen. Mir geht es ja erst mal nur darum, den Text auszulesen...)

 

Leider bleibt auch mit deinem Vorschlag, Hubert, die MsgBox leer.

 

 

    Datei := "test.xml"
    File := FileOpen(Datei, "r")
    len:=File.RawRead(var,File.length)
    Loop, % len//2  ; % fehlte, 4 statt 2, jedes 2. byte
    s.=chr(numget(var,2*(A_Index-1)+1,"UChar"))  ; 4 statt 2, ab Stelle 1 statt Stelle 2, UInt statt UChar
    Msgbox % s
 

Die chinesischen Zeichen sind mir durch einen Fehler passiert. Ich hatte aus Versehen eine normale UTF-8 XML eingelesen...



hd0202
  • Members
  • 709 posts
  • Last active: Feb 14 2016 08:05 PM
  • Joined: 13 Aug 2006
✓  Best Answer

Hallo Sheik,

mein Ansatz basierte auf dem Beispiel in deinem ersten Post, und das entspricht absolut nicht der Codierung in deiner eben gelieferten Datei.shocked.png

Hier meine zweite Anpassung zu nnnik's Version:

    File := FileOpen(Datei, "r")
    len:=File.RawRead(var,File.length)
    Loop, % len//4  ; % fehlte
    s.=chr(numget(var,4*(A_Index-1)+2,"UChar"))  ; 2 null-werte übergehen
    Msgbox % s

Außerdem halte ich dein Dateiformat für "big endian". Hier das Ergebnis meines Tests:

---------------------------
ucs2-cod.ahk
---------------------------
<?xml version="1.0" encoding="utf-32"?><TransactionMetaData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=
---------------------------
OK   
---------------------------

Hubert



Sheik
  • Members
  • 25 posts
  • Last active: Jan 09 2014 07:34 AM
  • Joined: 06 Nov 2012

Hallo Hubert,

 

zuerst vielen Dank für deine Hilfe. Nun klappts!

Leider versteh ich den Code noch nicht wirklich.

Loop, % len//4

Warum hier geteilt durch vier? Jedes zweite Zeichen ist ein NUL-Zeichen (zumindest laut Notepad++).

 

Chr() ist mir klar, jedoch nicht das NumGet(). Könntest du mir vielleicht kurz in Worten erklären, was die Funktion genau macht und wieso mal vier gerechnet wird?
 

mein Ansatz basierte auf dem Beispiel in deinem ersten Post, und das entspricht absolut nicht der Codierung in deiner eben gelieferten Datei.

 

Bitte entschuldige, ich habe im ersten Post lediglich angegeben, was mir mein Notepad++ angezeigt hat und das war (und ist immer noch) UC2 Little Endian. Daher auch der Screenshot als "Beweis". Worin der Unterschied zwischen Little Endian und Big Endian besteht, weiß ich nicht. Mit Dateikodierungen habe ich noch nicht wirklich Erfahrung...

 

Grüße

Sheik



hd0202
  • Members
  • 709 posts
  • Last active: Feb 14 2016 08:05 PM
  • Joined: 13 Aug 2006

Hallo Sheik,
hier ist die Hex-Anzeige von UltraEdit zu deiner Datei:

 

000   FF FE 00 00 3C 00 00 00 3F 00 00 00 78 00 00 00  ....<...?...x...
010   6D 00 00 00 6C 00 00 00 20 00 00 00 76 00 00 00  m...l... ...v...
020   65 00 00 00 72 00 00 00 73 00 00 00 69 00 00 00  e...r...s...i...
030   6F 00 00 00 6E 00 00 00 3D 00 00 00 22 00 00 00  o...n...=..."...
040   31 00 00 00 2E 00 00 00 30 00 00 00 22 00 00 00  1.......0..."...
050   20 00 00 00 65 00 00 00 6E 00 00 00 63 00 00 00   ...e...n...c...
060   6F 00 00 00 64 00 00 00 69 00 00 00 6E 00 00 00  o...d...i...n...
070   67 00 00 00 3D 00 00 00 22 00 00 00 75 00 00 00  g...=..."...u...
080   74 00 00 00 66 00 00 00 2D 00 00 00 33 00 00 00  t...f...-...3...
090   32 00 00 00 22 00 00 00 3F 00 00 00 3E 00 00 00  2..."...?...>...
0A0   3C 00 00 00 54 00 00 00 72 00 00 00 61 00 00 00  <...T...r...a...
0B0   6E 00 00 00 73 00 00 00 61 00 00 00 63 00 00 00  n...s...a...c...
0C0   74 00 00 00 69 00 00 00 6F 00 00 00 6E 00 00 00  t...i...o...n...
0D0   4D 00 00 00 65 00 00 00 74 00 00 00 61 00 00 00  M...e...t...a...
0E0   44 00 00 00 61 00 00 00 74 00 00 00 61 00 00 00  D...a...t...a...
0F0   20 00 00 00 78 00 00 00 6D 00 00 00 6C 00 00 00   ...x...m...l...
100   6E 00 00 00 73 00 00 00 3A 00 00 00 78 00 00 00  n...s...:...x...
110   73 00 00 00 69 00 00 00 3D 00 00 00 22 00 00 00  s...i...=..."...
120   68 00 00 00 74 00 00 00 74 00 00 00 70 00 00 00  h...t...t...p...
130   3A 00 00 00 2F 00 00 00 2F 00 00 00 77 00 00 00  :.../.../...w...
140   77 00 00 00 77 00 00 00 2E 00 00 00 77 00 00 00  w...w.......w...
150   33 00 00 00 2E 00 00 00 6F 00 00 00 72 00 00 00  3.......o...r...
160   67 00 00 00 2F 00 00 00 32 00 00 00 30 00 00 00  g.../...2...0...
170   30 00 00 00 31 00 00 00 2F 00 00 00 58 00 00 00  0...1.../...X...
180   4D 00 00 00 4C 00 00 00 53 00 00 00 63 00 00 00  M...L...S...c...
190   68 00 00 00 65 00 00 00 6D 00 00 00 61 00 00 00  h...e...m...a...
1A0   2D 00 00 00 69 00 00 00 6E 00 00 00 73 00 00 00  -...i...n...s...
1B0   74 00 00 00 61 00 00 00 6E 00 00 00 63 00 00 00  t...a...n...c...
1C0   65 00 00 00 22 00 00 00 20 00 00 00 78 00 00 00  e..."... ...x...
1D0   6D 00 00 00 6C 00 00 00 6E 00 00 00 73 00 00 00  m...l...n...s...
1E0   3A 00 00 00 78 00 00 00 73 00 00 00 64 00 00 00  :...x...s...d...
1F0   3D 00 00 00                                      =...

 

Wie du siehst, belegt jedes Zeichen 4 Stellen, deshalb die entsprechende Berechnung. Ausnahme sind die ersten 4 Stellen, die ersten 2 davon sind die File-Markierung und nach dem 'RawRead' nicht in der Variable 'var' enthalten, die anderen beiden werden übergangen und führen zu der Addition von 2 auf den Offset in 'numget'. Notepad++ nimmt hier offensichtlich schon eine Interprätation der Daten vor, während UltraEdit wirklich alle Stellen der Datei anzeigt.

Ich denke mittlerweise doch, dass deine Datei 'little endian' codiert ist, bei 'big endian' würden die letzten 4 Stellen '00 00 00 3D' aussehen und alle anderen Zeichen würden auch mit 3 NUL-Zeichen beginnen und mit dem jeweiligen Character enden.

Hubert
 



Sheik
  • Members
  • 25 posts
  • Last active: Jan 09 2014 07:34 AM
  • Joined: 06 Nov 2012

Hallo Hubert,

danke für die ausführliche Erklärung. In der HEX-Ansicht leuchtet mir das ganze schon mehr ein. Ich denke, dass ich es so in etwa verstanden habe wink.png

 

Danke auch an alle anderen für die Hilfe!



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Es ist UTF-32LE mit der BOM  FFFE0000. AHK und Notepad++ nehmen davon wohl nur den Teil FFFE wahr, und das ist leider die BOM für UTF-16LE. UCS-2 ist ein Vorgänger von UTF-16.


Prefer ahkscript.org for the time being.