Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Windows上使用Perl在名称长度超过220个字符的目录中创建文件_Windows_Perl_Ntfs - Fatal编程技术网

在Windows上使用Perl在名称长度超过220个字符的目录中创建文件

在Windows上使用Perl在名称长度超过220个字符的目录中创建文件,windows,perl,ntfs,Windows,Perl,Ntfs,我遇到一个问题,无法在名称长度超过220个字符的目录下创建文件 以下是一个测试脚本,它至少在我的机器上复制观察到的行为: use warnings; use strict; use Win32::LongPath; print system ('rmdir /s /q test'); mkdirL('test'); for my $i (200 .. 255) { my $dir_name = 'test/' . sprintf("%04d", $i) . ('a' x ($i-4)

我遇到一个问题,无法在名称长度超过220个字符的目录下创建文件

以下是一个测试脚本,它至少在我的机器上复制观察到的行为:

use warnings;
use strict;

use Win32::LongPath;

print system ('rmdir /s /q test');
mkdirL('test');

for my $i (200 .. 255) {

  my $dir_name = 'test/' . sprintf("%04d", $i) . ('a' x ($i-4));
  mkdirL($dir_name);

  openL(\my $fh, '>', "$dir_name/" . ('_' x 200) . '.txt') or die "$^E";
  print $fh 'Hello!';
# closeL $fh;
}
此脚本将在
0220aaaa…aaa/
下创建一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

是否存在此问题的原因?如何更改脚本,以便在所有目录中创建
*.txt
文件

更新: 脚本在运行时不会死掉或产生任何错误消息

更新2: 与其他问题一样,此问题在中没有答案,其答案清楚地表明,此路径长度限制是Windows问题,而不是NTFS问题。NTFS允许长度最多为32K个字符的路径

事实上,我的测试脚本能够创建最多255个字符的目录(正如NTFS规范所预期的那样),当目录名超过220个字符时,似乎不可能在目录中存储文件。

TL;博士 问题的根源是您试图验证文件是否已创建的方法。有关更多信息,请阅读下面的详细说明

事实如下:

  • perl
    在使用
    mkdirL
    openL
    调用时不会给出任何错误
  • perl
    可以使用
    openL
    打开创建的文件并读取内容
  • 因此,问题在于,无论您使用什么工具,要么使用ANSI版本的Windows API调用,要么指定相对路径,或者两者的组合,因此它们的路径限制为260个字符

    为了测试这一点,我在
    D:\t
    下运行了脚本。瞧,当
    $i=250
    时,GVim无法打开文件:

    D:\t
    是四个字符,
    \test
    是另外五个字符。因此,250+9=259,当您添加另一个
    \
    时,它会点击260

    使用
    shortpathL
    试试这个:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use Win32::LongPath;
    
    `cmd /c rd /s /q test`;
    
    mkdirL('test') or die "$^E";
    
    my $dir_length = 255;
    my $dir_name = 'test/'
                 . sprintf("%04d", $dir_length)
                 . ('a' x ($dir_length - 4))
    ;
    
    mkdirL($dir_name) or die "$^E";
    
    my $file_name = "$dir_name/" . ('z' x 200) . '.txt';
    
    printf "% 3d\n", length $file_name;
    
    openL(\my $fh, '>', $file_name) or die "$^E";
    
    print $fh "Hello!\n" or die "$^E";
    
    close $fh or die "$^E";
    
    system 'notepad.exe', shortpathL($file_name);
    
    您将获得:

    因此,请为无法使用Unicode接口的任何外部程序提供短路径

    冗长的解释 现在我已经有机会在一台计算机上实际尝试了这一点,我无法复制这个问题

    以下是我使用的代码:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use Win32::LongPath;
    
    `cmd /c rd /s /q test`;
    
    mkdirL('test')
        or die "$^E";
    
    for my $i (200 .. 255) {
        my $dir_name = 'test/' . sprintf("%04d", $i) . ('a' x ($i-4));
        mkdirL($dir_name) or die "$^E";
    
        my $file_name = "$dir_name/" . ('_' x 200) . '.txt';
    
        printf "% 3d\n", length $file_name;
    
        openL(\my $fh, '>', $file_name)
            or die "$^E";
    
        print $fh 'Hello!' or die "$^E";
    
        close $fh or die "$^E";
    }
    
    以下是输出:

    C:\…\Temp> perl tt.pl 410 411 412 413 414 415 … 460 461 462 463 464 465 产出:

    … 459 Hello! 460 Hello! 461 Hello! 462 Hello! 463 Hello! 464 Hello! 465 Hello! … 459 你好 460 你好 461 你好 462 你好 463 你好 464 你好 465 你好 因为
    Win32::LongPath
    内部规范化了路径,所以它们遵循“要指定扩展长度路径,请使用
    “\\?\”
    前缀”建议,然后使用Unicode版本的API调用,例如,
    openL
    不会遇到此类问题

    在该函数的ANSI版本中,名称仅限于
    MAX\u PATH
    个字符。要将此限制扩展到32767个宽字符,请调用该函数的Unicode版本,并在路径前添加“\\?\”
    。有关详细信息,请参阅

    如何验证文件是否已正确创建?


    另外,请参阅“”,了解有关

    的解释,是否收到任何错误消息?了解Windows上的问题:@Sobrique,此最大路径长度是Windows问题,而不是NTFS问题
    Win32::LongPath
    专门设计用于解决Windows问题并充分利用NTFS的潜力。此外,脚本将创建目录,直到其长度为255个字符,在目录中创建文件似乎是不可能的;Windows长路径支持不允许正斜杠。(当然,Win32::LongPath可能正在为您进行转换。)正是这样:我/Perl创建了这些文件,但试图使用文件资源管理器查看它们(正如您所指出的,我应该知道的),这是一个毫无意义、徒劳的练习。 … 459 Hello! 460 Hello! 461 Hello! 462 Hello! 463 Hello! 464 Hello! 465 Hello!