none
MoveFileExのコピー失敗した場合にコピー先のファイルが消失する RRS feed

  • 質問

  • 別のアプリケーションがCreateFileで「FILE_FLAG_BACKUP_SEMANTICS」をセットして開いた状態のフォルダに対して、MoveFileEx(sourFile, destFile, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)でCreateFileされているフォルダにファイル移動すると、移動先のファイルが消失してしまいます。ファイルはネットワークパスを使っています。MoveFileExの戻り値はFalseですが、GetLastErrorはエラーではありませんでした(この操作を正しく終了しました。)。このような症状の情報をご存知でしたら、教えていただきたいです。

    よろしくお願いいたします。

    2014年10月28日 10:20

回答

  • 1.MoveFileEx()はマニュアルにある通り、
     ローカルコンピュータ上のファイルを扱います。
     ネットワーク上のファイルを取り扱えるかどうかは説明されていません。
     従って、説明にない使い方の場合、その結果も保障されていないと考えられます。
    ちょっとひどいと思ったのでここだけ突っ込みます。MoveFileExのRemarksセクションには「In Windows 8 and Windows Server 2012, this function is supported by the following technologies.」としてServer Message Block (SMB) 3.0 protocolが挙げられています。質問者さんの使用されたOSやファイルサーバーのプロトコルなどは明示されてはいませんが、ネットワーク上のファイルもサポートしていると考えるべきではないでしょうか?
    # Win7以前やSMB 2.0以前について言及がないと言われればそうですが、Win8から急に変わるものでもないのでサポート対象と思います。
    • 回答としてマーク たう 2014年10月30日 4:36
    2014年10月29日 4:59
  • 佐祐理さん。ご指摘ありがとうございます。
    ひょっとするとご指摘の通りなのかもしれませんが、
    自分が注目したのは、当該関数の第一引数、第二引数の説明に、いちいち書いてある。

    >The current name of the file or directory on the local computer.
    >The new name of the file or directory on the local computer.

    の部分です。これを見る限り、自分にはネットワークパスが使えるようには思えませんでした。
    仮にネットワークパスが使用できるのなら、なぜわざわざこのように書いてあるのかわかりません。
    他の似たような関数、例えばCopyFileEx()には、この様な記述はありません。

    もちろんドライブに割り当てられたネットワーク上のフォルダは、
    仮想的ではありますが、ローカルコンピューター上のディレクトリと考えています。

    以上を勘案すると、現状のマニュアルの記述上はネットワークパスについては、
    恣意的にサポートしていないと明記してあることと同等の記述であると考えられます。
    従って、たとえ可能であっても、その使い方を製品に含めるべきではないと思います。

    2014年10月29日 6:15

すべての返信

  • やや質問内容を図りかねますので、思いついたことを記述してみます。

    1.MoveFileEx()はマニュアルにある通り、
     ローカルコンピュータ上のファイルを扱います。
     ネットワーク上のファイルを取り扱えるかどうかは説明されていません。
     従って、説明にない使い方の場合、その結果も保障されていないと考えられます。

    2.ディレクトリ(フォルダ)をどのようにオープンしたのかによって、
     そのディレクトリに対してできることが異なると考えられます。
     例えば、起動中のアプリが専用に使用するフォルダが、
     他から削除や書き換えができないようにオープンしている場合もありえます。
     というか、多くのケースがこれに当てはまります。
     従って、他アプリがオープンしているディレクトリに書き込めないのは、
     想定してしかるべき事態との認識をもっています。

    さて、この症状の情報を知りたいとのことですが、
    何かお困りのことがあるのでしょうか。
    残念ながら、文面からは読み取れませんでした。

    2014年10月29日 4:30
  • 1.MoveFileEx()はマニュアルにある通り、
     ローカルコンピュータ上のファイルを扱います。
     ネットワーク上のファイルを取り扱えるかどうかは説明されていません。
     従って、説明にない使い方の場合、その結果も保障されていないと考えられます。
    ちょっとひどいと思ったのでここだけ突っ込みます。MoveFileExのRemarksセクションには「In Windows 8 and Windows Server 2012, this function is supported by the following technologies.」としてServer Message Block (SMB) 3.0 protocolが挙げられています。質問者さんの使用されたOSやファイルサーバーのプロトコルなどは明示されてはいませんが、ネットワーク上のファイルもサポートしていると考えるべきではないでしょうか?
    # Win7以前やSMB 2.0以前について言及がないと言われればそうですが、Win8から急に変わるものでもないのでサポート対象と思います。
    • 回答としてマーク たう 2014年10月30日 4:36
    2014年10月29日 4:59
  • 佐祐理さん。ご指摘ありがとうございます。
    ひょっとするとご指摘の通りなのかもしれませんが、
    自分が注目したのは、当該関数の第一引数、第二引数の説明に、いちいち書いてある。

    >The current name of the file or directory on the local computer.
    >The new name of the file or directory on the local computer.

    の部分です。これを見る限り、自分にはネットワークパスが使えるようには思えませんでした。
    仮にネットワークパスが使用できるのなら、なぜわざわざこのように書いてあるのかわかりません。
    他の似たような関数、例えばCopyFileEx()には、この様な記述はありません。

    もちろんドライブに割り当てられたネットワーク上のフォルダは、
    仮想的ではありますが、ローカルコンピューター上のディレクトリと考えています。

    以上を勘案すると、現状のマニュアルの記述上はネットワークパスについては、
    恣意的にサポートしていないと明記してあることと同等の記述であると考えられます。
    従って、たとえ可能であっても、その使い方を製品に含めるべきではないと思います。

    2014年10月29日 6:15
  • 仲澤@失業者様、佐祐理様、ご回答ありがとうございます。

    ネットワークパスを使用することについて、解釈が分かれるようなものは使わない方がいいですね。

    2014年10月30日 4:35
  • FYI
    -------------------------------------------------------------
    MoveFileEx function

    http://msdn.microsoft.com/en-us/library/aa365240(v=vs.85).aspx

    MOVEFILE_COPY_ALLOWED2 (0x2)
    If the file is to be moved to a different volume,
    the function simulates the move by using the CopyFile and DeleteFile functions.
    If the file is successfully copied to a different volume and the original file is unable to be deleted,
    the function succeeds leaving the source file intact.
    This value cannot be used with MOVEFILE_DELAY_UNTIL_REBOOT.
    -------------------------------------------------------------

    2014年10月30日 4:57