in reply to Problems Opening file with Perl where path has UTF8

Dang. I need to add CreateFileW() to Win32API::File... ): I thought I had but it was Win32API::Registry that included the *W hooks...

Update: Short of that, I think you are stuck with only 8-bit characters when using open. So your options are likely:

  1. Switch to a locale where the file name only requires 8-bit characters
  2. Use the "short name" to open the file (at least I think that will work around this problem
  3. Rename the file (or, under NTFS, provide a hard link to the file using a name w/o problematic characters)

It is too bad that Win32.pm includes GetShortPathName() [which is GetShortPathNameA()] but not GetShortPathNameW().

Update: Yep, I checked the latest Perl source code and open under Win32 hasn't been made smart enough to handle UTF-8 strings.

ikegami mentioned (in the CB) using Win32::API to get access to CreateFileW(), which you could combine with Win32API::File's OsFHandleOpen() to get a Perl file handle to use.

- tye        

  • Comment on Re: Problems Opening file with Perl where path has UTF8 (sorry)

Replies are listed 'Best First'.
Re^2: Problems Opening file with Perl where path has UTF8 (d'oh!)
by tye (Sage) on Nov 23, 2006 at 03:20 UTC

    Um, actually, Win32API::File does have CreateFileW(), just not mentioned in the documentation.

    my $wPath= pack "S*", unpack( "C*", "C:/server/htdocs/DEVELOPMENT/testing/" ), 19968, 26869, 39640, 26641, unpack( "C*", "/test/test.ssi" ), 0; my $hFile= CreateFileW( $wPath, GENERIC_READ()|GENERIC_WRITE(), FILE_SHARE_READ()|FILE_SHARE_WRITE(), [], OPEN_EXISTING(), 0, [] ) or die "Can't open: $^E\n"; OsFHandleOpen( *DATFILE, $hFile, "rw" ) or die "Can't create Perl handle: $!\n"; my $strHeaderLine = <DATFILE>; print $strHeaderLine; close DATFILE;

    Note, this code is untested because I composed it under Linux.

    Update: I need to update createFile() to detect UTF-8 path names and do all this for you...

    - tye        

      Update: The striken text is only true for the system call CreateFileW, but not for Win32API::File's verion of CreateFileW.

      CreateFileW returns INVALID_FILE_HANDLE (-1) on error, not false.

      use constant INVALID_FILE_HANDLE => -1; my $hFile= CreateFileW( $wPath, GENERIC_READ()|GENERIC_WRITE(), FILE_SHARE_READ()|FILE_SHARE_WRITE(), [], OPEN_EXISTING(), 0, [] ); INVALID_FILE_HANDLE != $hFile or die "Can't open: $^E\n";

        Did you try this? Because the XS code and the documentation for Win32API::File's CreateFile() shows that a false value is returned on error.

        - tye        

Re^2: Problems Opening file with Perl where path has UTF8 (sorry)
by Anonymous Monk on Nov 23, 2006 at 18:51 UTC
    What about FindFirstFileW() (also not in Win32API::File) unfortunately, for opening directories in UTF-8? In perl's win32/win32.c - win32_open has deprecated USING_WIDE(), so there's no real option at this point. :( I'd really like to see File::Find work on Win32 with UTF-8 filenames & dirs. Thanks

      FindFirstFileA() isn't even in Win32API::File. Unfortunately, the complex structs used makes it less trivial to add; but I'll look into that. But that wouldn't help File::Find much. Better would be to fix readdir (and thus glob, I'd hope) on Win32 to use FindFirstFileW() and return UTF-8 file names only if the found files have names with non-8-bit characters in them (or perhaps non-7-bit characters), or perhaps do things backward compatably based on something in %ENV (well, I prefer using %ENV over some obscure internal Perl variable because I find such preferences easier to deploy).

      - tye        

        Yeah, readdir() needs work too.

        Anything that would help - I'm completely unable to read UTF-8 files on Windows right now.

        Thanks