質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

5828閲覧

ファイル移動時の更新日時が変わらない

loop_dog

総合スコア1

.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2021/04/09 20:51

編集2021/04/10 05:55

前提・実現したいこと

.NET core3.1でファイルの移動プログラムを作成しています。
言語はC#です。

発生している問題・エラーメッセージ

移動はできるのですが、ファイルの作成日時が実行した時間になります。
更新日時は移動元の日時になります。
希望としては作成日時も各ファイルの作成日時になってほしいと思っています。

《追記》
マウス操作やキーボード操作での「切り取り&貼り付け」ではきっちりと作成日時も移動先に引き継がれるのはなぜなのでしょうか。
プログラミングではダメで、マウス操作等では可能という状態もなぜそうなるのかも知りたいです。

エラーメッセージは特になし

該当のソースコード

C#

1 2 FileInfo fiSrc = new FileInfo(fullPathNameSrc); 3 FileInfo fiDst = new FileInfo(fullPathNameDst); 4 fiDst.Delete(); 5 6 fiSrc.MoveTo(fullPathNameDst, true); 7 8(もしくは) 9 File.Move(fullPathNameSrc, fullPathNameDst, true); 10 11

試したこと

オーバーライドをTRUEにしているので、そもそも問題はないと思いますが、
取りあえず、削除すれば更新日時は変わりますが、既にあった場合(=削除しない)、
作成日時、更新日時ともに変わりません。

補足情報(FW/ツールのバージョンなど)

VS2019

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

ファイルの移動をしたら作成日時が変わるのはwindowsの仕様だと思うので
作成日時を変えない方法はないと思います。
そういうものだと受け入れるのが良いかと思います。

と思ってたのですが、windows8.1でテストした所
同じドライブの場合、作成日時は変わらず
違うドライブへ移動した場合は、作成日時が変わるという結果になりました。

完全に仕様というわけでもなさそうですね。
どこからどこへという条件次第で変わる仕様のようですね。

で、そのままにするのは無理そうなので
作成日時を取得・設定する方法を使い、移動後に元の作成日時に戻す方法を
以下に記します。

ファイルのタイムスタンプ(作成日時、更新日時、アクセス日時)を取得、設定する

書いてある通り、移動前に

DateTime dt = System.IO.File.GetCreationTime(fullPathNameSrc);

で、作成日時を取得し、移動後に

System.IO.File.SetCreationTime(fullPathNameDst, dt);

で設定という感じで行けるかと思います。私の家の環境windows8.1では上手く行きました。
ただ、.Net Framework 4.7.2での評価です。
.Net coreでも同じだと思うのですが、どうでしょうか。

投稿2021/04/09 22:27

編集2021/04/09 22:59
xail2222

総合スコア1497

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/04/10 00:47

> どこからどこへという条件次第で変わる仕様のようですね。 同じドライブ(≒ディスク)上であればファイルの位置情報などを含むディレクトリ情報の書き換えだけで済むため、ファイル内容のコピーは行われず、従って新たにファイルが作られることも無い為ですね。違うドライブであればどうしてもこちらからあちらへファイル内容自体をコピーする必要があるので、新ファイルとして作成され、作成日時が発生します。多くのOSやファイルシステムでおおむね同じ動きになるはずです。コマンドや使うフレームワーク、ミドルウェアの移動、コピー操作にもよりますが、OSに近い低レベルのAPIやシステムコールでは違うドライブへの移動操作はそれだけでエラーになる場合もあります。
loop_dog

2021/04/10 04:31

>xail2222さん 次、試しますので、お待ちください。 私も似たような事を考えていたのですが。。 dodox86さんへの返答(マウス操作等のところ)が自分としてはどうしても気になるところです。 > dodox86さん (あとがきで申し訳ないですが)手動(マウス操作やキーボード)ではきっちりと作成日時もコピーされるのはなぜなのでしょうか。 プログラミングではダメで、手動では可能。 どこにその違いがあるのか。。。 残念ながら、そこまで調べる術を知らず。
xail2222

2021/04/10 04:58

System.IO.File.Move では日時変わりませんでした。 FileInfo で動かす場合の不具合ということでしょうか。 他の操作も色々調べると違いがあるかもしれないですね。
xail2222

2021/04/10 05:51 編集

バージョン違うかもですが https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.IO.FileSystem/src/System/IO/FileInfo.cs これがFileInfoのソースで、中では FileSystem.MoveFile(FullPath, fullDestFileName, overwrite); をやってるって書いてあってそれは https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Windows.cs#L18 中で Interop.Kernel32.MoveFile(sourceFullPath, destFullPath, overwrite) と書いてあるけど、そこから先がわーかーらーなーいー 調べれるのかな。 っていうか、調べ方あってるのかな。 System.IO.File.Moveも調べたら FileSystem.MoveFile(fullSourceFileName, fullDestFileName, overwrite); を使ってるって書いてあるし、なぜこちらは上手く行くのかよくわからないです。
loop_dog

2021/04/10 05:57

> xail2222さん > System.IO.File.Move では日時変わりませんでした。 既に移動先に同じ名前のファイル名がある場合で、 「変わらない」というのは移動元のファイル名が引き継がれるという事でしょうか。 ちなみに私、今は System.IO.File.Move で、試しているんですよねぇ。 > FileInfo で動かす場合の不具合ということでしょうか。 質問する前からも FileInfo.MoveTo でも試してはいます。 結局、どちらもダメなんですよねぇ。
loop_dog

2021/04/10 06:05

引用 ------------------------------------------------------------------------------------ https://docs.microsoft.com/ja-jp/dotnet/api/system.io.file.move?view=netcore-3.1#System_IO_File_Move_System_String_System_String_System_Boolean_ File.Move メソッド .NET Core 3.0 以降のバージョンでは、パラメーターを Move(String, String, Boolean) に設定し overwrite true て、ファイルが存在する場合はそれを置き換えることができます。 ------------------------------------------------------------------------------------ と書かれてあって、自分の条件では可能だと思うんですよね。 それが色々なパターンで出来ない、という状況に陥っています。 最初は削除した方がいいのかな、でもそもそもオーバーライトの意味合いって何? って調べてたら、上記に当たったので、じゃあ、移動先のファイルを削除するステップを削除して実行しても、移動元の作成日時は引き継がれませんでした。 結局、カーネルの方でコピーをしているのかなと思ってしまう今日この頃です。 (だけど、マウス操作等=手動では違うという。。。)
xail2222

2021/04/10 06:38 編集

System.IO.File.Moveで変わらなかったのは、勘違いかもです。今試したらかわってましたし 質問にも書いてましたね。すみません。 >結局、カーネルの方でコピーをしているのかなと思ってしまう今日この頃です。 同じドライブにあればアドレス変えるだけで移動できますが 物理的に違う場所にあればアドレス変えるだけじゃ出来なくて、データを新たに作るわけだから 作成日時が変わるのは自然なことだと思っていました。 マウス操作の時だけ特殊なことをしている。と考えるべきではないでしょうか。 ただ、それならコピーの時も作成日時をコピーするのが正しいんじゃないかとか思ったりします。
guest

0

書いて頂いたように

DateTime dt = System.IO.File.GetCreationTime(fullPathNameSrc);

で、作成日時を取得し、移動後に

System.IO.File.SetCreationTime(fullPathNameDst, dt);

これで対応しました。

投稿2021/04/12 19:16

loop_dog

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

MoveToじゃなくて、CopyToではどうでしょうか

投稿2021/04/09 22:13

y_waiwai

総合スコア87800

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

loop_dog

2021/04/10 04:24

CopyToに変えてもダメでした。 移動をしたいので、コピーではどうかな?という気持ちがありますねぇ。。。 まあ、コピー元のファイルを消す、という方法を入れればいいかもしれませんが。
y_waiwai

2021/04/10 04:57

移動をするなら、その様になるのは当然の話しで、 これをどうにかするなら、一旦ファイルを全部読み込んで、新規書き込みしないとダメだと思いますよ
loop_dog

2021/04/10 06:06

> 移動をするなら、その様になるのは当然の話しで、 お手数ですが、なぜ、当然の話になるのか、教えて頂けますか? (純粋に知りたいだけですので。。。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問