none
画像ファイルのコピー RRS feed

  • 質問

  • 画像ファイルをフラッシュメモリーからDドライブにコピーしようとしています。

    originalFolder = "H:\DCIM\100CANON";

    destinationFolder = "G:\";

    foreach (string path in Directory.GetFiles(originalFolder))

    と、コピー元のファイルをDataTableに格納して、コピー先のファイルにコピーするに辺り、今回は、下記の通り画像ファイルを時間順に並べ替えた上で1つずつ連番を振ってコピーしているためか、非常に遅くてどうしようもありません。

                    string oldName, newName;
                    DateTime date = new DateTime();
                    string oldPath;
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        int suffixLength = 0;
                        oldName = dt.Rows[i]["FileName"].ToString();
                        pos = oldName.LastIndexOf(".");
                        suffixLength = oldName.Length - pos;
                        suffix = oldName.Substring(pos, suffixLength);
                        name = oldName.Substring(0, pos);
                        date = Convert.ToDateTime(dt.Rows[i]["CreationTime"]);
                        newName = date.ToString("yyyy-MM-dd");
                        newName = newName + " (" + (i + 1) + ")" + suffix;
                        oldPath = dt.Rows[i]["Path"].ToString();
                        name = destinationFolder + newName;
                        File.Copy(oldPath, name, false);
                    }
    マウスですべての画像ファイルを選択して、一括してコピーするようにすばやくする方法はないものでしょうか?

    よろしくお願いします。

    2010年7月4日 16:27

回答

  • ”遅い”と主観的に評価するだけでなく、時間を計測するなど客観的な評価方法も織り込むようにしてください。
    (Stopwatch クラスを使うなど)

    複数のファイルのコピーはどんなプログラムであれ、基本的にループで回すことになります。
    それが API の中のループなのか、自分で書いたループなのかは状況によって変わりますが、顕著な速度差を生むものではないと考えています。

    ちなみに、File.Copy の行をコメントアウト(削除でも良い)した場合、どのくらいかかるのですか。
    Copy がない状態でも遅いのであれば、前処理が遅いと言うことになります。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク yasheeki 2010年7月19日 5:21
    2010年7月5日 22:51
    モデレータ

すべての返信

  • 質問はコピーをすばやくする方法ですが、一言で片付けられている&コードが示されていない「コピー元のファイルをDataTableに格納して」の部分が遅いということはありませんか?
    当然ながら、ExpolorerでのコピーではDataTableに格納することはありませんので、その部分でコピー時間に開きが出てきます。

    蛇足ですが、DataTableに格納する理由を教えてください。

    2010年7月4日 22:24
  • 余計なコードを書いてしまったために、無駄な憶測を生んでしまって申し訳ありません。また、destinationFolder = "G:\";は、destinationFolder = "D:\";の間違いでした。

    DataTable を使った理由は大したことではなくて、DataGridView に表示させて、ファイル名などを確かめたかったからで、今回の問題には何も関係ありません。

    ディレクトリの中にあるファイルをマウスなどで一括して移動することなどで、経験的に素早いと感じています。今回のようにfor ループによってファイルを一つずつコピーしていく方法では、一つ一つのファイルの移動が完了してからfor ループ内のコードを実行することで、また、名前を変えたりすることによって遅くなってしまうのでしょうか?

    ご指摘の内容は、コピー前にDataTable に格納する際の所要時間が遅いのではないかということと思いますが、コピーが遅いと感じているのは、デバッグの際にコピー元のファイルをDataTableに格納した後での時間に対して、遅く感じているということです。ただ、もしかして、遅いと感じるのは気のせいかもしれません。

    ちょっと気になっているのは、最初にファイルをすべてコピーしたうえで、名前を変えるのはその後でという方法が良いのかもしれません(これならば、コピー時に名前の変更にかかる時間がないので)。

    念のためお聞きしたいのは、for ループでファイルを一つ一つコピーすること自体は、一般には決して遅くないのかどうかです(foreach だと微妙に速いとかの問題ではなくてです)。問題がないレベルのはずであれば、そういうものとして受け止めたいのですが、いかがでしょうか?

    ただ、子のコード自体にはfor ループ内にnew 演算子を使ってインスタンスを生成しているわけではないので、遅いのは他の部分のコードでメモリを大量に使っているからかもしれません(実際はメモリに影響するようなことはしていないつもりでいるのですが)。

    この辺りで参考になるご意見を頂けるとありがたいです。

    2010年7月5日 15:29
  • ”遅い”と主観的に評価するだけでなく、時間を計測するなど客観的な評価方法も織り込むようにしてください。
    (Stopwatch クラスを使うなど)

    複数のファイルのコピーはどんなプログラムであれ、基本的にループで回すことになります。
    それが API の中のループなのか、自分で書いたループなのかは状況によって変わりますが、顕著な速度差を生むものではないと考えています。

    ちなみに、File.Copy の行をコメントアウト(削除でも良い)した場合、どのくらいかかるのですか。
    Copy がない状態でも遅いのであれば、前処理が遅いと言うことになります。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク yasheeki 2010年7月19日 5:21
    2010年7月5日 22:51
    モデレータ
  • 有益な情報をありがとうございます。

    「複数のファイルのコピーはどんなプログラムであれ、基本的にループで回すことになります。」とのことで、とても安心しました。

    で、File.Copy の行をコメントアウトすると、一瞬で処理が完了します。

    この辺りは、StopWatch を使って計測すべきかもしれませんが、現在はまだ計測していません。

    いずれにせよ、「処理方法は間違っていない」という確信を持たせていただいたことに感謝しています。その他のことがあれば、時間ができましたら報告させていただこうと思います。

    ありがとうございます。

    2010年7月7日 15:23
  • まじめにスピードをあげようとするのならFile.Copy()を複数スレッドで動かすとか。
    特に別ディスクへのアクセスなので、書き込み中に次のファイルの読み込みをしたりで、トータルの時間を減らすことができます。

    あとはどこまで細かく制御するか、です。

    2010年7月19日 7:49