本帖最后由 523066680 于 2019-1-16 16:25 编辑
same same- use File::Slurp;
- write_file("dst.txt", reverse(read_file("src.txt")));
复制代码 但是怎么能满足于此,不如假设文件大于10G,练练手吧。
tac.exe 测试超过3GB的文件,没有输出。
实践了,先用Perl试手,实测 3.0GB文件 70s,机械硬盘(蓝色标签)。- =info
- 文本按行倒序输出
- 523066680/vicyang
- 2019-01
- =cut
-
- use strict;
- use Fcntl qw(:seek);
- STDOUT->autoflush(1);
- my $src = "F:/A_Parts.txt";
- my $dst = $src;
- $dst =~s/(\.\w+)$/_REV$1/;
-
- reverse_write( $src, $dst );
-
- sub reverse_write
- {
- my ($srcfile, $dstfile) = @_;
- open my $SRC, "<:raw", $srcfile or die "$!\n";
- open my $DST, ">:raw", $dstfile or die "$!\n";
-
- # 缓冲区大小
- my $buffsize = 2**16;
- my $offset = -s $SRC;
- my $buff;
- my @lines;
- my $left = "";
- while ( $offset >= $buffsize )
- {
- $offset -= $buffsize;
- seek $SRC, $offset, SEEK_SET;
- read $SRC, $buff, $buffsize;
- # 拼接,考虑单行文本小于 $buffsize 的情况
- $buff = $buff . $left;
- if ( $buff =~/\r?\n/ ) {
- @lines = reverse( split /\r?\n/, $buff, -1 );
- $left = pop @lines;
- printf $DST "%s\r\n", join("\r\n", @lines);
- } else {
- $left = $buff;
- #printf "%s\n", $left;
- }
- }
-
- # 如果 offset 未归零,读取剩下(源文件的开头)部分
- return if ($offset <= 0);
- seek $SRC, 0, SEEK_SET;
- read $SRC, $buff, $offset;
- @lines = reverse(split /\r?\n/, $buff .$left );
- print $DST join("\r\n", @lines);
- close $SRC;
- close $DST;
- }
复制代码
|