如何使用 Perl 将数据从有缺陷的 DVD 复制到硬盘?
情况是这样的:我的系统(Win XP Pro)无法从DVD光盘复制一个巨大的视频文件(大约6GB),该文件可能有缺陷,划伤或其他什么,但可以用mplayer播放几帧虽然充满了马赛克。当复制过程持续一定时间长度时,系统将中止该工作并给出此警告“发生循环冗余校验校验和错误”。然后复制的所有内容都被自动删除。
我认为 Perl 应用程序可能会解决这个问题。我的想法是这样的:我一次复制一个meg的视频数据。如果发生读取错误,我会让 Perl 忽略这一特定的一兆数据,并继续一次一兆地复制视频的其余部分。
顺便说一句,我也注意到一些商业软件可以完成这项工作,但在试验中存在局限性。
以下脚本是我迄今为止尝试过的。它一次从有缺陷的 DVD 磁盘复制一兆数据,但它像 Win XP 一样失败。唯一的区别是 perl 不会删除已经复制的内容。就我而言,它复制了大约 900 兆的视频数据到我的硬盘,这 900 兆的视频部分仍然可以用 mplayer 播放。但我的目标是复制所有好的、大多数的,只留下所有坏的、少数的。
use strict;
use warnings;
$/ = \1_048_576;
open my $in, "<", 'D:\tobecopied.mkv' or die $!;
binmode $in;
open my $out, ">", 'E:\copied.mkv' or die $!;
binmode $out;
while (<$in>) {
print $out $_;
}
问题是我不知道如何实现这一目标。希望这里有人能给我提示或线索。一如既往地感谢:)
The situation is this: My system (Win XP Pro) is unable to copy a huge video file (around 6 gigs) from a DVD disk, which might be defective, scratched or whatever but which can be played back with mplayer with a few frames full of mosaic though. When the copying process lasted for a certain length of time, the system would abort the effort and give me this warning "A cyclic redundancy check checksum error occurred" . And then everything copied was automatically deleted.
I'm thinking a Perl app might solve the issue. My thought is this: I copy video data one meg at a time. If a reading error ever occurs, I let perl ignore this particular one meg of data and keep copying the rest of the video still one meg at a time.
Incidentally, I've also noticed that some commercial software can do the job, but there're limitations in the trials.
The following script is what I've tried so far. It copies data one meg at a time from the defective dvd disk but it fails like Win XP. The only difference is perl doesn't delete what has already been copied. For my case, it copied around 900 megs of video data to my hard disk and this 900 megs part of the video can still be played back with mplayer. But my goal is to copy all that is good, the majority, only leaving all that is bad, the minority.
use strict;
use warnings;
$/ = \1_048_576;
open my $in, "<", 'D:\tobecopied.mkv' or die $!;
binmode $in;
open my $out, ">", 'E:\copied.mkv' or die $!;
binmode $out;
while (<$in>) {
print $out $_;
}
The problem is I don't know how to achiev this. Hope someone here can give me a hint or clue. Thanks like always :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您想要 ddrescue,无需重新发明轮子。
您的程序中的
readline
不够低级,一个必须使用sysread
而不是可以指定偏移量来选择部分读取失败后上升。You want ddrescue, no need to reinvent that wheel badly.
readline
from your program is not low-level enough, one must usesysread
instead where an offset can be specified to pick up after a portion failed reading.