perl - 从 Perl 中具有数据偏移量的文件加载 zlib 压缩数据

标签 perl io compression zlib

我希望我的 Perl 脚本从文件加载二进制数据。但是,如果文件开头出现 _ISCOMPRESSED_ header ,则该文件可以直接加载,也可以需要解压缩 (zlib)。

我已经能够成功加载未压缩的文件并识别标题:

(open my ($fh), "<", $fileName) or (return 0);
binmode $fh;

my $fileHeader;
sysread $fh, $fileHeader, 14;
if( $fileHeader eq "_ISCOMPRESSED_" ){
  # Here, need to decompress the filestream and update the $fh to point toward uncompressed data 
}
else{
  # Read it from the begining
  sysseek $fh,0,0;
}

# Read the data using the file handle
sysread $fh,$self->{'sig'},4;
sysread $fh,$self->{'version'},4;

我现在想使用 Zlib 解压缩数据 block 并更新文件句柄 $fh 以分配未压缩的数据。

我应该怎么做?是否可以在不将未压缩数据写入磁盘的情况下完成此操作?

最佳答案

perl 附带的解压模块可以从现有的打开文件句柄中读取。读取将从当前偏移量开始,从而可以轻松跳过标题。 IO::Uncompress::* 模块特别创建可与普通 I/O 函数一起使用的文件句柄对象,以允许透明使用;创建后,您的代码并不关心它是压缩的还是纯源文件。像这样的东西:

#!/usr/bin/env perl
use warnings;
use strict;
# I don't have a zlib-flate to test for sure; I think this is the right module
use IO::Uncompress::Inflate;

my $fileName = "data.compressed";

my $fh;
open my $realfh, "<:raw", $fileName
    or die "Unable to open $fileName: $!\n";
read $realfh, my $header, 14;
if ($header eq "_ISCOMPRESSED_") {
    $fh = IO::Uncompress::Inflate->new($realfh, AutoClose => 1)
        or die "Unable to open decompression stream!\n";
} else {
    seek $realfh, 0, 0;
    $fh = $realfh;
}

read $fh, $self->{'sig'}, 4;
read $fh, $self->{'version'}, 4;
# etc.
close $fh;

如果您像您看起来那样进行大量小型输入操作,我会使用 read 而不是 sysread 来利用内部缓冲。但重要的是要保持一致;在同一个文件句柄上混合两种形式将导致看似丢失数据的问题。

关于perl - 从 Perl 中具有数据偏移量的文件加载 zlib 压缩数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73519099/

相关文章:

c++ - LZW压缩生成文件比原来大

php - 哪个 Blowfish 算法最多 'correct' ?

Perl运算符: $|++; dollar sign pipe plus plus

java - 使用 Java EE 和 primefaces 从 MySQL 下载文件

java - 写入 servlet 流

java - FileDescriptor.in 与 System.in

c# - 重命名 ICSharpCode.SharpZipLib.dll

perl:不显眼地写入由 TAP::Formatter::HTML 打开的 IO::Handle

regex - 计算一个字符串在另一个字符串中出现的次数(Perl)

c# - 有关压缩/解压缩技术的文档