python脚本尝试处理硬盘坏道导致io错误视频文件无法复制问题

这里给大家分享一下windows下移动硬盘遇到坏道导致io错误通过脚本强制复制的方法。

自从开始玩FPV后,外出游玩都会随手拍摄视频,平时都会将视频素材复制到移动硬盘中。
前几天在想着剪辑视频,于是想着把视频复制到自己电脑中的时候报错了。

提示“由于I/O设备错误,无法运行此项请求”

在网上搜索了一下,尝试的使用CMD后,输入CHKDSK E:/R进行修复,但是还是无法复制。

于是我又想到了DiskGenius的坏道检测功能。经过长时间的等待,不出所料扫描出了不少坏道。而在点击修复的时候,提示修复会损坏原有的文件,于是我出于安全考虑暂时没有进行修复。那怎么办呢??

还好手头有空闲的硬盘,我将没有损坏的文件全部复制到另外一块空闲硬盘中,单独对几个无法复制的文件进行处理。

思路是这样的:

通过Python循环逐块读取文件,当读取到某处发生IOError的时候,填充指定长度的空数据,并跳过错误块。
为了尽可能的快速,但又能尽量较少的跳过错误长度,使其文件尽可能接近原始情况,所以在读取到错误时,减少读取大小,读取成功时逐步增大读取块的大小。

代码:

指定好读取大小与损坏的文件路径, 默认复制文件到代码执行目录下。

import os

blk_size = 2*1024*1024  # 读取大小
skip = 512  # 跳过大小


def copy(file_path):
    global blk_size, skip
    count = 0
    rd_len = 0  # 已读取长度
    f = open(file_path, 'rb+')
    fsize = os.path.getsize(file_path)
    fname = os.path.basename(file_path)
    ff = open(fname, 'wb+')
    b_size = blk_size
    while True:
        try:
            buf_copy = f.read(b_size)
            if buf_copy:
                rd_len = len(buf_copy)+rd_len  # 统计已读取大小
                os.system('cls') #清理控制台
                # print(fname, count+1, str(rd_len)+'/'+str(fsize))
                print(fname, count+1, str(int(rd_len*100/fsize))+"%")
                ff.write(buf_copy)
                count += 1
            else:
                break
            if blk_size > b_size+skip:
                b_size = b_size+skip  # 逐步增加读取大小
            else:
                b_size = blk_size
        except IOError:
            f.close()
            f = open(file_path, 'rb+')
            print('err:', rd_len)
            rd_len = rd_len+skip
            ff.write(bytes(skip))  # 补充空数据
            b_size = skip  # 错误时将读取大小设置成跳过大小
            print("====> ", f.seek(rd_len, 0))  # 重置读取起始点
            continue
    f.close()
    ff.close()


for file_path in ['A.mp4','C.mp4']:# <<====自行修改为错误文件路径
    copy(file_path)

实测对于视频文件来说效果还行,可能某一帧后声音出现问题,但可以播放,但图片文件可能出现打不开或只能加载一般的可能,其他文件没有测试。

当时因为慌忙恢复数据,所以都忘记截图了,所以文章没有图片示例。

最后赶紧将坏的硬盘进行坏道修复,重新格式化了。

推荐阅读更多精彩内容