Perl中Win32::LongPath模块chdirL、getcwdL功能异常问题求解
问题原因
- 你遇到的
chdirL无法切换目录、getcwdL返回路径截断的问题不是使用方式错误,而是受限于Windows系统本身的机制和Win32::LongPath的实现缺陷:- Windows操作系统对进程的当前工作目录(CWD)默认有260字符的长度限制,该限制独立于文件系统的长路径支持,即使修改注册表开启系统长路径权限,进程CWD的长度限制依然存在,
chdirL底层调用系统CWD相关API,天然无法突破该限制。 - 你用
system 'CD'验证目录切换的方式本身无效:system会启动独立的cmd子进程,子进程的工作目录继承自Perl脚本启动时的初始目录,不会同步Perl进程内部的CWD变更。 getcwdL返回路径长度固定为249是模块的实现缺陷,该函数内部调用Win32 API时只分配了250字符的固定缓冲区,超过长度的内容会被直接截断。
- Windows操作系统对进程的当前工作目录(CWD)默认有260字符的长度限制,该限制独立于文件系统的长路径支持,即使修改注册表开启系统长路径权限,进程CWD的长度限制依然存在,
解决方案
由于你无法修改注册表开启长路径支持,不需要依赖切换工作目录的逻辑即可实现长路径处理:
- 废弃所有
chdirL、getcwdL相关调用,全程使用绝对路径调用Win32::LongPath提供的文件操作函数,mkdirL、openL、testL、unlinkL等函数本身支持传入超过260字符的绝对长路径,不受系统CWD长度限制。 - 你现有代码中的目录、文件操作已经全部使用了绝对路径,直接删除循环内切换目录、获取当前目录的相关代码即可正常运行。
# 修改后可正常运行的核心逻辑示例 use strict; use warnings; use Readonly; use File::Spec::Functions; use Win32::LongPath; my $dir = 'd123456789'; my $file = 'test.txt'; my $long_path = 'C:\\Temp'; my $long_file; my $fh; Readonly::Scalar my $MAX_PATH => 512; while ( length $long_path < $MAX_PATH ) { $long_path = catdir $long_path, $dir; $long_file = catfile $long_path, $file; printf "%-5d: %s\n", length $long_path, "Making $long_path..."; mkdirL $long_path or die "mkdir failed: $^E"; printf "%-5d: %s\n", length $long_file, "Making $long_file..."; openL \$fh, '>', $long_file or die "unable to create file: $^E"; print {$fh} "$long_path\n" or die "unable to print to file: $^E"; close $fh or die "unable to close file: $^E"; last if ( !( testL 'e', $long_path ) ); last if ( !( testL 'e', $long_file ) ); } unlinkL $long_file or warn "unable to delete file: $^E"; 1;
内容的提问来源于stack exchange,提问作者Flandraco
相关产品推荐
相关产品推荐

