Perl HTTP 多线程下载合并之换行符错误

来源:互联网 发布:mac os 原版dmg镜像 编辑:程序博客网 时间:2024/05/16 12:21

写了一个小程序,用HTTP多线程下载并合并文件,核心下载代码如下:

    my $ua = LWP::UserAgent->new;
    my $head = HTTP::Request->new(GET => $url,
                                 HTTP::Headers->new(
                                    Range => "bytes=$start-$end"
                                    #这个头用来标记部分下载开始结束位置
                                 )
                                 );
    my $resp = $ua->request($head);
    open FILE,">C:/tmp/txt_$partial.dat";
    print FILE $resp->content;
    close FILE;

合并代码如下:

    open FILE,'>c:/tmp/final.txt';
    for(1..n){
        open TMP,"c:/tmp/txt_$_.dat";
        $r = sysread TMP,$buf,1024*10;
        while($r){
            syswrite FILE,$buf,1024*10;
            $r = sysread TMP,$buf,1024*10;
        }
        close TMP;
    }
    close FILE;

使用一个rar文件作为测试用途,结果发现合并后的代码无法打开,而且字节数有增加。换一个文本文件txt作测试,结果发现前后对比如下

前:
  Accept-Language: zh-cn
  UA-CPU: x86
  Accept-Encoding: gzip, deflat
后:
  Accept-Language: zh-cn^M
  UA-CPU: x86^M
  Accept-Encoding: gzip, deflate^M

可以明显看到,每一行的结束多了一个符号^M,这又是由于在不同系统中换行符的不同造成的。Windows编辑器产生换行回车两个符号/n/r,而unix下只有一个/n,经过socket中间的传输转化就会在不同的系统产生错误。

解决方法,在下载分割文件的时候,写入时使用syswrite写入分割块大小的数据,则产生的文件不会有错误。代码如下

    my $ua = LWP::UserAgent->new;
    my $head = HTTP::Request->new(GET => 'http://localhost/PerlCGI/key.txt',
                                 HTTP::Headers->new(
                                    Range => "bytes=$start-$end"
                                 )
                                 );
    my $resp = $ua->request($head);
    syswrite FILE,$resp->content,1024*1000;
    close FILE;

每次都用一个小程序来扩充并测试一些功能,在此基础上解决发现的问题并继续完善发展自己的代码。

原创粉丝点击