这里给大家分享一下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)
实测对于视频文件来说效果还行,可能某一帧后声音出现问题,但可以播放,但图片文件可能出现打不开或只能加载一般的可能,其他文件没有测试。
当时因为慌忙恢复数据,所以都忘记截图了,所以文章没有图片示例。
最后赶紧将坏的硬盘进行坏道修复,重新格式化了。
网友评论