HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0112
centerbcopy命令等のファイルコピー命令を使ってコピーを行い途中経過(コピー率(%))を表示したい12未解決


center

リンク

2009/1/12(Mon) 18:40:50|NO.22742

bcopy命令等のファイルコピー命令を使ってコピーを行い途中経過(コピー率(%))を表示したいのですが、
できますでしょうか?



この記事に返信する


check

リンク

2009/1/12(Mon) 18:44:14|NO.22743

bcopyを何回も行っているならできる。
4回なら1回終わったら25%終わったことに。
1回の中での経過率を求めたいのなら、そういう命令を自作すれば?
というか、1回だけならHSPでもまあまあ早いから経過率出すほどでもないだろ。



center

リンク

2009/1/12(Mon) 18:53:43|NO.22744

checkさん
回答ありがとうございます。

>1回の中での経過率を求めたいのなら、そういう命令を自作すれば?
それを「どのようにすれば良いか」聞きたいのですが・・・
>というか、1回だけならHSPでもまあまあ早いから経過率出すほどでもないだろ。
巨大ファイル(100-300GB程度)を扱うソフトウェアを開発中なので、必要だと思っております。
・・・かなり大きなファイルなので時間は凄い事になりますが。。



check

リンク

2009/1/12(Mon) 19:07:05|NO.22745

よく調べてないけど、こことか?
http://hspnext.com/hspkura/hspkura04.htm#contents12



 

リンク

2009/1/12(Mon) 19:48:15|NO.22746

・全体のファイルサイズ÷1回当たりの転送サイズ=ループ回数
・(ループ回数÷100)×100=1ループ辺りの進捗率
・現在の進捗率を初期化

ループ始まり
  ・ファイル転送
  ・現在の進捗率+=1ループ辺りの進捗率
  ・経過表示
ループ終わり

・100%にして進捗表示

大まかにこんな感じ。



シモン

リンク

2009/1/12(Mon) 20:07:10|NO.22748

だぶん、bloadとbsaveをリピート内で繰返せばいいのではないかと…

1.existで、コピー元のファイルサイズをとっておく
2.コピーに使うバッファメモリのサイズ固定(メモリが少なくても転送できるように)
3.バッファメモリサイズ*回数
4.コピーしたサイズをファイルサイズで割ってお好きなように加工

たとえば、100MBのファイルを1MBずつbloadとbsaveでリピートを使いコピーして
(1MB*cnt/100MB)*100をリピートごとに更新していく


コピーに使うバッファメモリのサイズ固定転送方法は、
下の一番最後のほうにあるバッファメモリサイズの固定したファイルの転送方法が
使えると思います。

ttp://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200604/06060037.txt

こんな方法ではどうでしょうか?



Kpan

リンク

2009/1/12(Mon) 20:40:09|NO.22751

進行状況の表示が第一の目的じゃないなら、システムに放り投げては?
(時間がかかる場合は、システムの方で進行状況ダイアログが表示される)

SHFileOperation関数
http://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200801/08050033.txt
http://yokohama.cool.ne.jp/chokuto/urawaza/struct/SHFILEOPSTRUCT.html



center

リンク

2009/1/12(Mon) 21:21:02|NO.22755

checkさん、 さん、シモンさん、Kpanさん、
回答ありがとうございます。

>よく調べてないけど、こことか?
折角探してくれたのにすみません。
私の勉強不足か、あまり分りませんでした。。

>大まかにこんな感じ。
大体は分りました。ありがとうございます。

>だぶん、bloadとbsaveをリピート内で繰返せばいいのではないかと…
仰るとおりホームページを見まして、色々してみたのですが、
下のがそのスクリプトです。

#define BUFFERSIZE 1048576;バッファサイズを1MBに指定 #define fn "ファイル名";コピーするファイル名 sdim buf,BUFFERSIZE;バッファ確保 exist fn : filesize = strsize;ファイルサイズ取得 //初回はファイルを作成しないといけない(?)為、ここで処理。(他に良い方法は無いかな??) bload fn,buf,BUFFERSIZE,BUFFERSIZE*cnt;コピー元1ブロック(1MB)初回読み込み bsave "[コピー]"+fn+"",buf,BUFFERSIZE;コピー先1ブロック(1MB)初回書き込み repeat (filesize/BUFFERSIZE)-1,1 title "コピー中・・・("+(cnt+1)+"/"+filesize/BUFFERSIZE+")" bload fn,buf,BUFFERSIZE,BUFFERSIZE*cnt;コピー元1ブロック(1MB)読み込み bsave "[コピー]"+fn+"",buf,BUFFERSIZE,BUFFERSIZE*cnt;コピー先1ブロック(1MB)書き込み wait 1 loop
・・・まだコピー率(%)はやってないのですが、
これで求め方と言うか、どうすれば良いかイマイチ分らないのですが、どうすれば良いでしょうか?
また、一応動く形にはしているのですが、スクリプトも結構問題があると思うので、そちらも指摘してもらえると幸いです。



center

リンク

2009/1/12(Mon) 21:25:24|NO.22756

・・・おっとすみません。Kpanさんのアドバイスの返事を書き忘れました。。
>進行状況の表示が第一の目的じゃないなら、システムに放り投げては?
「ダイアログが出る」と言うのは初耳ですね。。(勉強不足)
えっと、、なるべく独自でやりたいので。。(あとで色々とできるので)



シモン

リンク

2009/1/12(Mon) 22:26:59|NO.22760

以前、組んだプログラムに同じようなコードがありましたので参考までに。

ちなみに、私はHSPをはじめてまだ4ヶ月ぐらいのうえ、
以下のコードは2ヶ月目くらいのときに組んだので、
うまい方から見ると「おいおい」…というコードかもしれません。

私自身がわかり易いように書いていたので、コード内の変数名もそのままです。

ファイルパスとファイル名は適当に入力して試してみてください。


#define BUFFERSIZE 1048576;バッファサイズを1MBに指定 *onembcopy exist FilePath : FileSize = strsize if(FileSize < BUFFERSIZE){ sdim File,FileSize bload FilePath,File,FileSize bsave NewFilePath,File,FileSize }else{ sdim File,BUFFERSIZE sdim MstrSize,64 MstrSize = FileSize \ BUFFERSIZE sdim count,64 count = (FileSize / BUFFERSIZE) bsave NewFilePath,FileSize,0 repeat if(cnt = count){ sdim File,MstrSize bload FilePath,File,MstrSize,BUFFERSIZE*cnt bsave NewFilePath,File,MstrSize,BUFFERSIZE*cnt break }else{ bload FilePath,File,BUFFERSIZE,BUFFERSIZE*cnt bsave NewFilePath,File,BUFFERSIZE,BUFFERSIZE*cnt } title "コピー中・・・"+int(( BUFFERSIZE*cnt/FileSize )*100)+"%" ;たぶんこんな感じでいいのではないかと wait 1 loop } return

このやり方のコピーは、
条件分けしないとコピー後のファイルサイズが変わってしまうことがあります。

例えば、条件分けしないと100.5MBのファイルをコピーした1MBずつコピーしたときに
出来たファイルが101MBになってしまったりします。


進捗状況をGUI等で表示したいなら、
Kpanさんのページに行ってプログレスバーの情報等を勉強すると早いです。

私もわからなくなると、よくKpanさんのページにお世話になりに行きます。



center

リンク

2009/1/14(Wed) 20:29:06|NO.22814

シモンさん、
回答ありがとうございます。

サンプルスクリプトを、FilePathにコピー元ファイル名、NewFilePathにコピー先ファイル名を入れて動かしてみたのですが、
コピー率(%)がずっと0%のままでした。
どう言う事なんでしょう?



elfizm

リンク

2009/1/14(Wed) 22:02:41|NO.22824

centerさんが上で示されているスクリプトの問題点はシモンさんの言うとおり。
コピー元のファイルサイズがBUFFERSIZEで割り切れない場合は、正確にファイルをコピーできていません。

その点と、スクリプト中の「(他に良い方法は無いかな??)」の部分を踏まえて
改変してみましたので参考までにどうぞ。
最初の #define がその部分ですが、わからなければあまり気にしなくても良いです。

ちなみにシモンさんのサンプルは%表示の部分において、整数同士を割っているため
%が正しく表示されません。実数への変換( double )が必要です。
下のスクリプトと見比べてみるとわかりやすいと思います。


#define bsave2(%1,%2,%3=64,%4=0) if %4==0 : bsave %1,%2,%3 : else : bsave %1,%2,%3,%4 // ↑ bsaveの第4パラメータが0の時は新規作成するような「bsave2」を定義。 #const BUFFERSIZE 1024*1024 ; バッファサイズを1MBに指定 #define fn "ファイル名" ; コピーするファイル名 sdim buf,BUFFERSIZE ; バッファ確保 exist fn : filesize = strsize ; ファイルサイズ取得 nokori = filesize ; この3つの変数に toWrite = BUFFERSIZE ; 着目すると流れが offset = 0 ; わかりやすいと思います。 repeat if nokori < BUFFERSIZE : toWrite = nokori; 最終ブロックのサイズはBUFFERSIZEとは限らない。 bload fn,buf,toWrite,offset ; コピー元1ブロック読み込み bsave2 fn+"_copied",buf,toWrite,offset ; コピー先1ブロック書き込み nokori -= toWrite ; 書き込んだ分(toWrite)だけ nokori を減らす。 offset += toWrite ; 書き込んだ分(toWrite)だけ offset を増やす。 title "コピー中・・・( " + int( 100.0 * ( double(offset) / double(filesize) ) ) + " % )" if nokori==0 : break ; 残りサイズが0になったらコピー完了。 wait 1 loop



シモン

リンク

2009/1/14(Wed) 23:14:10|NO.22837

>elfizmさま
ご指摘ありがとうございます。
しばらく前にこの掲示板で実数の計算の質問を見ていたのに頭から抜け落ちていました。


 title "コピー中・・・"+int((double(BUFFERSIZE*cnt)/double(FileSize))*100)+"%" ;100%を出したい場合にはloop外にも title "コピー終了・・・100%" を書いた方がいい

初心者の私と違ってうまい方が書かれるコードは違いますね。
こういう風に組むのかととても参考になります。

私のコードは、以前組んだプログラムに使ったもので
コピーした後に元のファイルと同じタイムスタンプを…
それで、作ってみたら…「これ、ファイル同期ソフトじゃないの?」となってしまい
お蔵入りになっていたものでしたので、他の人の役に立ってよかったです。


>centerさま、
どちらも一つのファイルごとのパーセンテージしか出ません。
つまり、一ファイルごとに0〜100%を繰返します。

なので、フォルダごと等の複数ファイルをコピーするときには、
効率があまりよくない気がしますが、
ファイルリスト等を作ってリピートなどで繰り返し

"現在コピー中のファイル(リピート内ならcnt+1とか) / コピーするファイルの数(リストをnotemax等で取得)"

等の表示を付け加えるともっと進捗状況がわかり易くなると思います。
もちろん、もっと効率のいい方法があればその方法がいいのですが…

以上 蛇足でした。



ONION software Copyright 1997-2023(c) All rights reserved.