Nele Kosog: Schreiben und lesen von Dateien mit Unicode Zeichen auf Windows

Beitrag lesen

Hallo!

Ich versuche vergeblich eine von mir angelegte Datei, deren Name Unicode Zeichen enthält, wieder zu lesen.

Mein System: Windows XP, Perl Camelbox 5.10.0.

Angelegt wird die Datei so:

  
use utf8;  
  
use strict;  
use warnings;  
use diagnostics;  
  
use Encode qw( encode decode );  
use Symbol qw( gensym );  
use Win32API::File qw(  
  CreateFileW  
  OsFHandleOpen  
  CREATE_ALWAYS  
  OPEN_EXISTING  
  GENERIC_WRITE  
  GENERIC_READ  
);  
  
my @lines     = ();  
my $file_name = "йбный.txt";          # Beispielhafter Dateiname zum Testen  
my $content   = "пйрнобый";           # Beispielhafter Inhalt zum Testen  
my $encoding  = "UTF-8";              # Encoding UTF-8  
  
### WRITE  
  
my $win32_file_handle = CreateFileW(  
    encode( 'UTF-16LE', $file_name ), # Encode file name  
    GENERIC_WRITE,                    # For writing  
    0,                                # Not shared  
    [],                               # Security attributes  
    CREATE_ALWAYS,                    # Create and replace  
    0,                                # Special flags  
    [],                               # Permission template  
)  
or die("CreateFile: $^E\n");  
  
OsFHandleOpen(  
    my $fh = gensym(),                # Create global reference  
    $win32_file_handle,               # File handle  
    'w',                              # Open for writing  
)  
or die("OsFHandleOpen: $^E\n");  
  
print $fh encode(                     # Write to file  
    $encoding,                        # Encoding is UTF-8  
    $content,                         # File content in UTF-8  
);  
  
[...]  

Bis hierhin funktioniert es.

Recherche:

  • Der Dateiname wird im Explorer korrekt dargestellt.
  • Notepad zeigt den Inhalt korrekt an.
  • Andere Editoren zeigen den Inhalt korrekt an, wenn sie explizit auf UTF-8 umgestellt werden.

Ich versuche die Datei danach wie folgt zu lesen:

  
[...]  
  
### READ  
  
my $win32_file_handle = CreateFileW(  
    encode( 'UTF-16LE', $file_name ), # Encode file name  
    GENERIC_READ,                     # For reading  
    0,                                # Not shared  
    [],                               # Security attributes  
    OPEN_EXISTING,                    # Open existing  
    0,                                # Special flags  
    [],                               # Permission template  
)  
or die("CreateFileW: $^E\n");  
  
OsFHandleOpen(  
    my $fh = gensym(),                # Create global reference  
    $win32_file_handle,               # File handle  
    'r'                               # Open for reading  
)  
or die("OsFHandleOpen: $^E\n");  
  
while (<$fh>) {                       # Read lines  
    push @lines,  
      decode( $encoding, $_ );        # Decode UTF-8  
}  
  

Das Programm bricht beim Lese-Aufruf von CreateFileW mit der Fehlermeldung "The system cannot find the file specified [...]".
Das lese ich als "System kann die angegebene Datei nicht finden" - aufgrund des Dateinamens? Ich bin mittlerweile betriebsblind - ich sehe den Fehler einfach nicht. Doppeltes Encoding?

Alle Tipps sind willkommen!
Vielen Dank für eure Hilfe,
Nele