Perl转换带BOM的UTF-8 DAT文件时丢失表头问题求助
修复UTF-8带BOM转无BOM时丢失表头的Perl代码问题
你的代码里有个明显的逻辑错误导致表头丢失:在while(<SRC>){ @array = <SRC>; }这行,第一次执行<SRC>时已经读取了文件的第一行(也就是表头),但你没有把这行存入数组,而是直接在循环内部将剩余所有行读进@array,结果表头就被直接丢弃了。
下面是修正后的代码,既能保留完整的表头和数据,又能正确转换为无BOM的UTF-8格式,同时保留CRLF换行:
use strict; use warnings; use open qw( :encoding(UTF-8) :std ); # 默认启用UTF-8编码,读取时自动跳过BOM sub encodeWithoutBOM { my ($src_path, $des_path) = @_; # 更清晰的参数命名 print("Copying content from $src_path to $des_path\n"); # 使用词法文件句柄(比全局句柄更安全,自动关闭) open(my $src_fh, '<', $src_path) or die "Couldn't open source file: $!"; # 强制输出CRLF换行,跨平台兼容,同时指定无BOM的UTF-8编码 open(my $des_fh, '>:crlf:encoding(UTF-8)', $des_path) or die "Couldn't open destination file: $!"; # 一次性读取所有行,包括表头 my @all_lines = <$src_fh>; # 将所有行写入目标文件 print $des_fh @all_lines; # 词法文件句柄会在函数结束时自动关闭,无需手动close } # 调用示例(替换成你的实际文件路径) # encodeWithoutBOM('input_with_bom.dat', 'output_no_bom.dat');
关键改进点说明:
- 修复表头丢失问题:直接用
my @all_lines = <$src_fh>一次性读取文件所有行,确保第一行表头被完整保留。 - 更安全的文件处理:使用词法文件句柄(
$src_fh、$des_fh)替代全局文件句柄,避免命名冲突,且文件会自动关闭,减少资源泄漏风险。 - 强制保留CRLF换行:在打开输出文件时添加
:crlf层,确保无论在Windows还是类Unix平台,输出文件都使用CRLF换行符。 - 自动处理BOM:
:encoding(UTF-8)会自动跳过输入文件的UTF-8 BOM,同时输出时不会添加BOM,完美符合你的需求。 - 代码可读性优化:用参数解构和清晰的变量名替代模糊的
$_[1]、$_[2],让代码更易维护。
内容的提问来源于stack exchange,提问作者PKV
相关产品推荐
相关产品推荐

