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

Beitrag lesen

Es funktioniert dann doch etwas anders.

Zum Beispiel so:

  
use utf8;  
binmode STDOUT, ":encoding(UTF-8)";  
binmode STDIN,  ":encoding(UTF-8)";  
  
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  
  );  
  
### Test Case  
my $encoding  = 'UTF-8';               # Encoding UTF-8  
my $file_name = 'пробный/пробный.txt'; # File name for testing purposes  
my $content   = 'пйрнобый';            # File content for testing purposes  
  
### Write file  
write_file( file_name => $file_name, encoding => $encoding, content => $content, );  
  
### Read file  
my @lines = read_file( file_name => $file_name, encoding => $encoding, );  
  
### Output  
foreach (@lines) { print $_; }  
  
  
###----------------------------------------------------------------------------  
sub read_file {  
###----------------------------------------------------------------------------  
### USAGE: read_file(  
###                     file_name => <file name>,  
###                     encoding => <your encoding>,  
###                 );  
###----------------------------------------------------------------------------  
	#shift;  
	my %parameter = @_;  
	my @lines     = ();  
	if ( defined $parameter{file_name} && $parameter{file_name} ne '' ) {  
		if ( defined $parameter{encoding} && $parameter{encoding} ne '' ) {  
  
			my $win32_file_handle = CreateFileW(  
				encode( 'UTF-16LE', $parameter{file_name} ),  
				GENERIC_READ,        # For reading  
				0,                   # Not shared  
				[],                  # Security attributes  
				OPEN_EXISTING,       # Open existing file  
				0,                   # Special flags  
				[],                  # Permission template  
			  )  
			  or die("CreateFileW: $^E\n");  
  
			OsFHandleOpen( my $rfh = gensym(), $win32_file_handle, 'r' )  
			  or die("OsFHandleOpen: $^E\n");  
  
			while (<$rfh>) {  
				push @lines, decode( $encoding, $_ );  
			  }  
		  }  
	  }  
	else {  
		die("Cannot write file. No file name defined.");  
	  }  
	return @lines;  
}  
  
###----------------------------------------------------------------------------  
sub write_file {  
###----------------------------------------------------------------------------  
### USAGE: write_file(  
###                       file_name => <file name>,  
###                       encoding => <your encoding>,  
###                       content => <your content>,  
###                   );  
###----------------------------------------------------------------------------	  
	#shift;  
	my %parameter = @_;  
	if ( defined $parameter{file_name} && $parameter{file_name} ne '' ) {  
		if ( defined $parameter{encoding} && $parameter{encoding} ne '' ) {  
  
			my $win32_file_handle = CreateFileW(  
				encode( 'UTF-16LE', $parameter{file_name} ),  
				GENERIC_WRITE,    # For writing  
				0,                # Not shared  
				[],               # Security attributes  
				CREATE_ALWAYS,    # Create and replace  
				0,                # Special flags  
				[],               # Permission template  
			  )  
			  or die("CreateFileW: $^E\n");  
  
			OsFHandleOpen( my $wfh = gensym(), $win32_file_handle, 'w' )  
			  or die("OsFHandleOpen: $^E\n");  
  
			print $wfh encode( $parameter{encoding}, $parameter{content} );  
		  }  
	  }  
	else {  
		die("Cannot write file. No file name defined.");  
	  }  
}  
  

Einschränkungen:

  • Erstmal Angabe des Devices (z.B. C:) nicht möglich.
  • Löschen der Datei nicht getestet.

Verbesserungsvorschläge sind willkommen!
Viele Grüße,
Nele