Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I copy a file with a UTF-8 filename to another UTF-8 filename in Perl on Windows?
    primarykey
    data
    text
    <p>For example, given an empty file <code>テスト.txt</code>, how would I make a copy called <code>テスト.txt.copy</code>?</p> <p>My first crack at it managed to access the file and create the new filename, but the copy generated <code>テスト.txt.copy</code>.</p> <p>Here was my first crack at it:</p> <pre><code>#!/usr/bin/env perl use strict; use warnings; use English '-no_match_vars'; use File::Basename; use Getopt::Long; use File::Copy; use Win32; my ( $output_relfilepath, ) = process_command_line(); open my $fh, '&gt;', $output_relfilepath or die $!; binmode $fh, ':utf8'; foreach my $short_basename ( glob( '*.txt') ) { # skip the output basename if it's in the glob if ( $short_basename eq $output_relfilepath ) { next; } my $long_basename = Win32::GetLongPathName( $short_basename ); my $new_basename = $long_basename . '.copy'; print {$fh} sprintf( "short_basename = (%s)\n" . " long_basename = (%s)\n" . " new_basename = (%s)\n", $short_basename, $long_basename, $new_basename, ); copy( $short_basename, $new_basename ); } printf( "\n%s done! (%d seconds elapsed)\n", basename( $0 ), time() - $BASETIME, ); # === subroutines === sub process_command_line { # default arguments my %args = ( output_relfilepath =&gt; 'output.txt', ); GetOptions( 'help' =&gt; sub { print usage(); exit }, 'output_relfilepath=s' =&gt; \$args{output_relfilepath}, ); return ( $args{output_relfilepath}, ); } sub usage { my $script_name = basename $0; my $usage = &lt;&lt;END_USAGE; ====================================================================== Test script to copy files with a UTF-8 filenames to files with different UTF-8 filenames. This example tries to make copies of all .txt files with versions that end in .txt.copy. usage: ${script_name} (&lt;options&gt;) options: -output_relfilepath &lt;s&gt; set the output relative file path to &lt;s&gt;. this file contains the short, long, and new basenames. (default: 'output.txt') ---------------------------------------------------------------------- examples: ${script_name} ====================================================================== END_USAGE return $usage; } </code></pre> <p>Here are the contents of <code>output.txt</code> after execution:</p> <pre><code>short_basename = (BD9A~1.TXT) long_basename = (テスト.txt) new_basename = (テスト.txt.copy) </code></pre> <p>I've tried replacing <a href="http://perldoc.perl.org/File/Copy.html" rel="noreferrer">File::Copy</a>'s copy command with a system call:</p> <pre><code>my $cmd = "copy \"${short_basename}\" \"${new_basename}\""; print `$cmd`; </code></pre> <p>and with Win32::CopyFile:</p> <pre><code>Win32::CopyFile( $short_basename, $new_basename, 'true' ); </code></pre> <p>Unfortunately, I get the same result in both cases (<code>テスト.txt.copy</code>). For the system call, the print shows <code>1 file(s) copied.</code> as expected.</p> <p>Notes:</p> <ul> <li>I'm running Perl 5.10.0 via <a href="http://strawberryperl.com/" rel="noreferrer">Strawberry Perl</a> on Windows 7 Professional</li> <li>I use the <a href="http://search.cpan.org/~jdb/Win32-0.39/Win32.pm" rel="noreferrer">Win32</a> module to access long filenames</li> <li>The glob returns short filenames, which I have to use to access the file</li> <li>テスト = test (tesuto) in <a href="http://en.wikipedia.org/wiki/Katakana" rel="noreferrer">katakana</a></li> <li>I've read <a href="http://perldoc.perl.org/perlunitut.html" rel="noreferrer">perlunitut</a> and <a href="http://joelonsoftware.com/articles/Unicode.html" rel="noreferrer">The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload