破損ファイルの復旧 pythonスクリプト version 5

2019/11/18 15:33 by yamasyuh68
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
破損ファイルの復旧 pythonスクリプト
191116
# 単純コピースクリプト

- HDが妖しくなってきたので換装、同期を取っていたら特定のファイルでソフトが反応しなくなった
大きな動画、強制終了してその動画を再生してみたら止まる箇所があり、多分同じ場所だと思う
しかしシークして飛ばすとまた再生される
動画が止まった部分のHDのセクタが不良で読み取れないのだと仮定
- で、動画を少しずつ読み込んで書き出すスクリプトを自作
読込がエラーで帰ってきたらそこは0で埋める構想だったが、システムは遅くても結局読み込んでくれたのでエラー処理部分はメッセージ程度しか書いてない


```
import os , sys ,  datetime

fname = r'<target--fullpath>'
out= r'<out--fullpath>'

size = os.path.getsize( fname )
volume = 1024  # 1024 64 8

try:
    size2 = os.path.getsize( out )
except:
    size2 = 0

fr=open( out , 'ab' )
f = open( fname , 'rb')

for i in range( size2 , size , volume ) :

    sys.stdout.write( f'\r {i:,} / {size:,}  --- {datetime.datetime.now()}' )
    sys.stdout.flush()

    f.seek( i )
    try :
        data = f.read( volume )
        fr.write( data )
    except :
        print(f'\r\n error --- position {i:,}')

f.close()
fr.close()

input( '\r\n finished ---- press any key ......' )
```
- 時間がかかるので途中でやめても次回起動したら続きから始めるように作った
やめるのはコンソールなので窓を閉じる(×ね)、ちょっと強引だけど
- 読み込むバイト数は volume 変数で決める
1024を基本としたが読み込まないセクションが多いようだともっと少なくしても良い
- 進捗を表示するのにスクロールしないように作った
ナカナカ良いわ( ´∀`)




# スレッド化してコピー速度監視

- 読込に時間がかかるセクションについて、経過時間を表示するようにした
前の単純スクリプトをスレッドにして、メインで進捗と経過時間を一秒おきに表示する仕組み
スレッドの変数をグローバルにして参照してる
こういうやり方が正解なのかどうかはよくわかんないけど思った通り動いてます

```
import os , sys , time , threading

pos = 0
size = 0
flag = False

def copy():

    ##### ここにデータを書く ##########################
    fname = r'<target--fullpath>'
    out= r'<out--fullpath>'

    global size
    size = os.path.getsize( fname )
    volume = 1024  ########### 1024 64 8  数字を小さくするほど遅い
    
    try:
        size2 = os.path.getsize( out )
    except:
        size2 = 0
    
    fr=open( out , 'ab' )
    f = open( fname , 'rb')

    for i in range( size2 , size , volume ) :
        global pos
        pos = i
        f.seek( i )
        try :
            data = f.read( volume )
            fr.write( data )
        except :
            print(f'\r\n error --- position {i:,}')
    
    f.close()
    fr.close()
    global flag
    flag = True


thread = threading.Thread(target = copy )
thread.start()

pos2=0
count=0
while 1:
    if(flag):
        break
    if pos2==pos:
        count+=1
    else:
        count=0
    sys.stdout.write( f'\r{pos:,} / {size:,}--{count} ' )
    sys.stdout.flush()
    pos2=pos
    time.sleep(1)

input( '\r\n finished ---- press any key ......' )
```

- 途中でやめるときにコンソールを落とすのはいかにも野蛮で気に入らない
キー入力を受け付けてもらって途中でストップできるようにしたいが
メインルーチンで毎秒表示するときにキー入力をチェックできないかな??
それをフラグにしてスレッドの中で参照すれば良い
- input を使ってしまうと入力待ちになっちゃうからなあ
どうしたらいいんだ?
Qtだとウインドウへに対するキーの入力判定が出来たはずだが



---
 --> [その他もろもろの開発](https://mimemo.io/m/p5be8G9RdeoWxkE)      

191116

単純コピースクリプト

  • HDが妖しくなってきたので換装、同期を取っていたら特定のファイルでソフトが反応しなくなった
    大きな動画、強制終了してその動画を再生してみたら止まる箇所があり、多分同じ場所だと思う
    しかしシークして飛ばすとまた再生される
    動画が止まった部分のHDのセクタが不良で読み取れないのだと仮定
  • で、動画を少しずつ読み込んで書き出すスクリプトを自作
    読込がエラーで帰ってきたらそこは0で埋める構想だったが、システムは遅くても結局読み込んでくれたのでエラー処理部分はメッセージ程度しか書いてない
import os , sys ,  datetime

fname = r'<target--fullpath>'
out= r'<out--fullpath>'

size = os.path.getsize( fname )
volume = 1024  # 1024 64 8

try:
    size2 = os.path.getsize( out )
except:
    size2 = 0

fr=open( out , 'ab' )
f = open( fname , 'rb')

for i in range( size2 , size , volume ) :

    sys.stdout.write( f'\r {i:,} / {size:,}  --- {datetime.datetime.now()}' )
    sys.stdout.flush()

    f.seek( i )
    try :
        data = f.read( volume )
        fr.write( data )
    except :
        print(f'\r\n error --- position {i:,}')

f.close()
fr.close()

input( '\r\n finished ---- press any key ......' )
  • 時間がかかるので途中でやめても次回起動したら続きから始めるように作った
    やめるのはコンソールなので窓を閉じる(×ね)、ちょっと強引だけど
  • 読み込むバイト数は volume 変数で決める
    1024を基本としたが読み込まないセクションが多いようだともっと少なくしても良い
  • 進捗を表示するのにスクロールしないように作った
    ナカナカ良いわ( ´∀`)

スレッド化してコピー速度監視

  • 読込に時間がかかるセクションについて、経過時間を表示するようにした
    前の単純スクリプトをスレッドにして、メインで進捗と経過時間を一秒おきに表示する仕組み
    スレッドの変数をグローバルにして参照してる
    こういうやり方が正解なのかどうかはよくわかんないけど思った通り動いてます
import os , sys , time , threading

pos = 0
size = 0
flag = False

def copy():

    ##### ここにデータを書く ##########################
    fname = r'<target--fullpath>'
    out= r'<out--fullpath>'

    global size
    size = os.path.getsize( fname )
    volume = 1024  ########### 1024 64 8  数字を小さくするほど遅い
    
    try:
        size2 = os.path.getsize( out )
    except:
        size2 = 0
    
    fr=open( out , 'ab' )
    f = open( fname , 'rb')

    for i in range( size2 , size , volume ) :
        global pos
        pos = i
        f.seek( i )
        try :
            data = f.read( volume )
            fr.write( data )
        except :
            print(f'\r\n error --- position {i:,}')
    
    f.close()
    fr.close()
    global flag
    flag = True


thread = threading.Thread(target = copy )
thread.start()

pos2=0
count=0
while 1:
    if(flag):
        break
    if pos2==pos:
        count+=1
    else:
        count=0
    sys.stdout.write( f'\r{pos:,} / {size:,}--{count} ' )
    sys.stdout.flush()
    pos2=pos
    time.sleep(1)

input( '\r\n finished ---- press any key ......' )
  • 途中でやめるときにコンソールを落とすのはいかにも野蛮で気に入らない
    キー入力を受け付けてもらって途中でストップできるようにしたいが
    メインルーチンで毎秒表示するときにキー入力をチェックできないかな??
    それをフラグにしてスレッドの中で参照すれば良い
  • input を使ってしまうと入力待ちになっちゃうからなあ
    どうしたらいいんだ?
    Qtだとウインドウへに対するキーの入力判定が出来たはずだが

--> その他もろもろの開発