Perl:寻找和读取位,而不是字节

时间:2014-08-26 15:58:16

标签: perl file bit

在Perl中,我想寻找文件的第n位(不是字节),然后读取下一个m位,作为0和1的列表返回。

有没有简单的方法可以做到这一点?

我意识到我可以写一个包含常规搜索和阅读的子程序,但是想知道是否有更简单的解决方案。

3 个答案:

答案 0 :(得分:2)

  

bitseek会一次抓取一组位。

seek($fh, int($bit_num/8), SEEK_SET);
my $offset = $bit_num % 8;
read($fh, my $buf, ceil(($offset+$num_bits)/8));
  

我正在寻找位寻址,而不是逐位读取。

vec($bits, $offset+$bit_num, 1);

答案 1 :(得分:1)

如果n是m的倍数,m是1,2,4,8,16,32之一,并且在某些平台上,64,则可以将整个文件读入字符串并使用{{3}为此。

(不可否认,这是一个相当有限的案例,但却很常见。)

除此之外,你只需要做数学计算;在伪代码中:

discard = n % 8;
startbyte = (n - discard) / 8
bits = m + discard
bytes = int( (bits + 7) / 8 )
seek to startbyte
read bytes into string
@list = split //, unpack "${bits}b", string
splice( @list, 0, $discard ) 
splice( @list, $m, @list )

答案 2 :(得分:0)

我最终写了类似@ikegami和@ysth建议的东西。供参考:

=item seek_bits($fh, $start, $num) 

Seek to bit (not byte) $start in filehandle $fh, and return the next 
$num bits (as a list). 

=cut 

sub seek_bits { 
  my($fh, $start, $num) = @_; 
  # the byte where this bit starts and the offset 
  my($fbyte, $offset) = (floor($start/8), $start%8); 
  # the number of bytes to read ($offset does affect this) 
  my($nbytes) = ceil($num+$offset)/8; 

  seek($fh, $fbyte, SEEK_SET);  
  read($fh, my($data), $nbytes); 
  my(@ret) = split(//, unpack("B*", $data)); 
  # return requested bits 
  return @ret[$offset-1..$offset+$num]; 
}