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

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

新規登録して質問してみよう
ただいま回答率
85.40%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

Q&A

解決済

2回答

799閲覧

テキストファイルの更新日時を更新する内容がうまく行かないです

tamanaga

総合スコア1

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

0グッド

1クリップ

投稿2024/07/12 12:07

実現したいこと

Aと言うフォルダに中身が0バイトの「a.txt」を置き、JavaのソースコードにBと言うフォルダに「a.txt」をコピーして、コピーした「a.txt」の更新日時を更新する内容で改修したいです。

発生している問題・分からないこと

Aと言うフォルダに中身が0バイトの「a.txt」をBと言うフォルダに「a.txt」をコピーする事ができました。しかし、Bと言うフォルダにある「a.txt」の更新日時が更新されず、苦戦をしています。

エラーメッセージ

error

1エラーメッセージは表示されずコンパイルが通って、Bと言うフォルダに「a.txt」をコピーする事ができました。しかし、Bと言うフォルダにある「a.txt」の更新日時が更新されないです。

該当のソースコード

Java

1import java.nio.file.Path; 2import java.nio.file.Paths; 3import java.nio.file.Files; 4import java.io.IOException; 5import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; 6import java.io.File; 7import java.util.Calendar; 8 9public class JSample{ 10 public static void main(String[] args){ 11 Path p1 = Paths.get("C:/code/A/a.txt"); 12 Path p2 = Paths.get("C:/code/B/ a.txt "); 13 14 try{ 15 //コピー先のファイルが既に存在していた場合に例外を発生させるのではなくコピー元のファイルをコピーした新しいファイルで置き換え 16 Files.copy(p1, p2, REPLACE_EXISTING); 17 }catch(IOException e){ 18 System.out.println(e); 19 } 20 } 21 public void lastModified() throws IOException{ 22 File file = new File("C:/code/B/ a.txt "); 23 //Calendarクラスのオブジェクトを生成する 24 Calendar cal = Calendar.getInstance(); 25 //初期化する 26 cal.clear(); 27 28 //日時を設定する 29 cal.getTime(); 30 //ファイルに日時セットする 31 file.setLastModified(cal.getTimeInMillis()); 32 } 33} 34

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Bと言うフォルダに「a.txt」をコピーする事ができました

補足

■参考URL
①ファイルやディレクトリをコピーする
https://www.javadrive.jp/start/file/index11.html
②更新日時を取得する
https://qiita.com/fumikomatsu/items/b98cc4d0dee782323096

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

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

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

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

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

int32_t

2024/07/12 14:23

どうやって『「a.txt」の更新日時が更新されず』という現象を確認しましたか? 更新日時がどうなるべきで、実際はどうなっていたのでしょうか。
neko_the_shadow

2024/07/12 23:31

mainメソッド内でlastModifiedメソッドを呼び出していないようです。mainメソッド内でlastModifiedを呼び出していて、かつ、最終更新日時が更新されていないソースコードを提示できますか?
tamanaga

2024/07/13 02:06

int32_tさん 説明不足で申し訳ございません Bと言うフォルダに「a.txt」があって、フォルダのウィンドウでそのテキストファイルの更新日時を見るとAと言うフォルダにある「a.txt」と言う同じ現象であると言う事です。 更新日時はプログラムを動かしたシステム日時であるべきです。例えば、Aと言うフォルダにある「a.txt」を作成した時間が昨日の7/12の10時だとして、プログラムを動かすとBと言うフォルダに同じテキストファイルがコピーされて更新日時が本日の7/13の11:06。翌日に動かすと7/14の11:06と言うように更新日時が更新されると言うプログラムです。
tamanaga

2024/07/13 02:09

neko_the_shadowさん 確かにメインメソッド内にlastModifiedメソッドを呼び出していないですね・・・ その辺りを少し検討して修正を試みます
hiroki-o

2024/07/13 05:16

>更新日時はプログラムを動かしたシステム日時であるべきです。 エクスプローラーでファイルのコピーをしてみるとわかりますが、それは更新日時ではなく、作成日時のほうです。
tamanaga

2024/07/13 11:48

IT業界にいてシステムの運用保守をメインに仕事をしているのですが、時々システムの改修をする事があり、久々に当たりました。いきなりは厳しいのでまずは簡易的なものと言う事でソースコードを記載しました。 neko_the_shadowさん Javaの基本であるメインメソッドに他のメソッドの処理を入れるのを忘れてしまいました。申し訳ございません。 19・20行目の間に「lastModified();」を入れてコマンドプロンプトで実行した所、「staticでないメソッドlastModified()をstaticコンテキストから参照する事はできません」とエラーが発生しました
tamanaga

2024/07/13 11:53

hiroki-oさん 更新日時がAと言うフォルダにある、「a.txt」と同じと言う事ですね・・・ コピー先のファイルの日時を更新するコマンドがもしご存知でしたら、ご教授いただければ幸いです・・・
otn

2024/07/13 13:02

やりたいことは、 Aと言うフォルダある「a.txt」を別のBと言うフォルダに「a.txt」と同じファイル名でコピーして、コピー先のBにある「a.txt」の更新日時をコピーを実施した日時にしたいです。 ということでいいのでしょうか? Java縛りは必須ですか?バッチファイルでやれば簡単明快ですけど。 あとは、作成日時をどうするかですね。 コピー先にすでに同名の a.txt が存在する場合に、一旦消して再作成するか(作成日時もコピーを実施した日時になる)、上書きするか(作成日時は上書き前と変わらず)かについて、希望があるのか、どうでも良いのか。
tamanaga

2024/07/13 14:30

otnさん 下記の件、 >Aと言うフォルダある「a.txt」を別のBと言うフォルダに「a.txt」と同じファイル名でコピーして、コピー先のBにある「a.txt」の更新日時をコピーを実施した日時にしたいです。 おっしゃる通りです システムではタスクスケジューラで設定して動かしています。毎週1回ある曜日の時間になると、タスクスケジューラが設定しているバッチファイルを起動して、バッチファイルの中にあるJavaやSQL文のファイルを読んで処理される仕組みになっています。 コピー先のBにある「a.txt」の更新日時をコピーを実施した日時にするのにJavaで実現厳しそうなら、バッチファイルにします。 希望はBにある「a.txt」は出力時に更新日時が更新されれば、良いです。そうなると、コピー先に既に同名の「a.txt」が存在する場合に一旦消して再作成するか(作成日時もコピーを実施した日時になる)の方になると言う事でしょうか。
退会済みユーザー

退会済みユーザー

2024/07/14 04:18 編集

質問記載の下記行、無駄な空白入ってませんか? Path p2 = Paths.get("C:/code/B/ a.txt "); あとJDKのバージョン、OSは書いた方がいいです(Windowsだと思うけど、ファイルシステム依存もあると思うので)。最近のJavaはLTSとかあって、現在は多分JDK21がLTSです(次が25らしい)。LTSでないもののサポートは半年しかありません。 一応なぜLastModifiedが変更されないか?ですが、それはNTFSの仕様だからです。現在確認できるMS謹製の資料が見当たらなかったのですが、以前出していたKnowledgeBaseのアーカイブでは以下のようになっています。 https://mskb.pkisolutions.com/kb/299648 Calendarクラスを使用する方法はhiroki-oさんが書いているようにすればいいのですが(多分元の実装意図を組んでそうしてるのだと思う)、このケースではLocaleなどに依存しないjava.util.Dateクラスを使う方が簡便です。 p.toFile().setLastModified(new Date().getTime());
guest

回答2

0

ベストアンサー

Windows 11、OpenJDK 22.0.1で確認しました。

otnさんが既にバッチで回答していますが、こちらはJavaで回答します。
以下のソースで要件は満たしていると思います。

import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.io.IOException; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import java.io.File; import java.util.Calendar; public class JSample{ public static void main(String[] args){ Path p1 = Paths.get("C:/code/A/a.txt"); Path p2 = Paths.get("C:/code/B/a.txt"); try{ //コピー先のファイルが既に存在していた場合に例外を発生させるのではなくコピー元のファイルをコピーした新しいファイルで置き換え Files.copy(p1, p2, REPLACE_EXISTING); lastModified(p2); }catch(IOException e){ System.out.println(e); } } public static void lastModified(Path p) throws IOException{ File file = p.toFile(); //Calendarクラスのオブジェクトを生成する Calendar cal = Calendar.getInstance(); //ファイルに日時セットする file.setLastModified(cal.getTimeInMillis()); } }

投稿2024/07/13 16:04

hiroki-o

総合スコア847

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

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

tamanaga

2024/07/16 15:12

回答ありがとうございます。試したところ問題が解決しました! ベストアンサーに選ばせていただきました。 本日それを基に担当者に見させていただきました。対応方法としては問題は無かったのですが、ツールの共有保存先が年に1回あるかないかの頻度で変わる事があります。そうなるとパスを直書きで記載すると再度修正する手間が発生するため、Javaだけでなくバッチファイルにも少し改修が必要と言う事でプラスα対応している所です。そのため、一旦解決済と言う事でベストアンサーと致しました。 ありがとうございました。
jimbe

2024/07/16 18:32

少し勘違いされているように感じましたので書かせていただきますが、 >対応方法としては問題は無かったのですが(中略)少し改修が必要と言う事でプラスα対応している所です。そのため、一旦解決済と言う事で(後略) teratail の質問は質問者の案件のサポートではありませんので、質問した件が解決したのでしたら("一旦"では無く)それで終わりと考えた方が良いです。 もし、(質問者の案件としては一続きであったとしても)『ファイルの更新日時を更新する方法』とは違う質問をされるのでしたら、別の質問を立てられた方が Q&A として情報の独立性が高まるのではないでしょうか。 (その際に過去の経緯としてこの質問へのリンクを載せておけば、回答者は必要に応じて調べることも出来ます。)
guest

0

コピー先のBにある「a.txt」の更新日時をコピーを実施した日時にするのにJavaで実現厳しそうなら、バッチファイルにします。

Javaでももちろん可能でしょうが、バッチファイルの方が簡単簡明です。
単にコピーすると、更新日時もコピーされるのでNUL(空ファイル)と連結することで加工してのコピー扱いにします。これで、コピー先ファイルの更新日時はcopyコマンド実行終了時刻になります。

ケース1:ファイル名が固定で決まっていて1つだけの場合

CMD

1setlocal 2set DIR_FROM=C:\A 3set DIR_DEST=C:\B 4set FILE=a.txt 5 6pushd %DIR_FROM% 7if exist %DIR_DEST%\%FILE% %DIR_DEST%\%FILE% 8copy %FILE%/b+NUL %DIR_DEST%\%FILE%

ケース2:ファイル名が固定で決まっているが複数ある場合

CMD

1setlocal 2set DIR_FROM=C:\A 3set DIR_DEST=C:\B 4 5pushd %DIR_FROM% 6for %%F in (a.txt b.txt c.txt) do ( 7 if exist %DIR_DEST%\%%F %DIR_DEST%\%%F 8 copy %%F/b+NUL %DIR_DEST%\%%F 9)

ケース3:拡張子txtのファイルが全部対象

CMD

1setlocal 2set DIR_FROM=C:\A 3set DIR_DEST=C:\B 4 5pushd %DIR_FROM% 6for %%F in (*.txt) do ( 7 if exist %DIR_DEST%\%%F %DIR_DEST%\%%F 8 copy %%F/b+NUL %DIR_DEST%\%%F 9)

簡明重視で書きましたが、ファイル名やフォルダー名に空白が含まれている場合は少し修正が必要です。

追記(補足)

最後の方の、copy %%F/b+NUL %DIR_DEST%\%%Fですが、同じ結果がtype %%F >%DIR_DEST%\%%Fで得られることに気づいたので、こちらに書き直した方がさらに簡明ですね。「 /b+NUL って何だろう?」とか調べる必要がなくなる。

投稿2024/07/13 15:17

編集2024/07/15 01:22
otn

総合スコア85458

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

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

tamanaga

2024/07/14 12:55

hiroki-oさん・otnさん お休みの中、お教え頂きましてありがとうございます hiroki-oさんの方は試した所、うまく行きました otnさんの方は更新日時が更新されなかったので、ファイル名やフォルダー名の修正を試してみます 明日は祝日で会社はお休みのため、火曜日に実際のソースコードを入れるなどをしてどちらかを使用すれば良いのかを検討します
otn

2024/07/14 13:11 編集

> otnさんの方は更新日時が更新されなかったので、 コードを書き換えて、/b+NUL を削除してしまったのですかね? 意味を100%理解しない状態で、コードを書き換えてはいけませんよ。 > 単にコピーすると、更新日時もコピーされるのでNUL(空ファイル)と連結することで加工してのコピー扱いにします。これで、コピー先ファイルの更新日時はcopyコマンド実行終了時刻になります。 と説明文も入れてたのですが。どこか理解できない部分がありましたでしょうか? 回答には書いてませんでしたが、+ による連結時には、各ファイル名の後に /B とバイナリーモードを示すオプションも必要です。これはCOPYコマンドの文法を調べれば分かることなので、きっと調べるだろうと思って省略しました。
退会済みユーザー

退会済みユーザー

2024/07/14 13:40

一応書いておきますが、copyコマンドの複数ファイル指定時の挙動はUnixライクなOSのcatコマンドに近いです。純粋なコピーではないし、そこまで一般的な使い方でもないので(catの代わりとして昔からバイナリ用途でよく使われていましたが(NULは/dev/null))、MS-DOS由来のコマンドをそんなに一生懸命勧める必要はないと思いますよ。 いざというとき、別のOSでも動くJavaを使うのも業務なら良い選択だと思います。
otn

2024/07/15 01:19

簡単簡明を重視すると、バッチですね。+ や /b は、copy /? に出てくるコマンドの基本機能だし。 と思ったら、「type コピー元 > コピー先」で十分だったようです。こちらの方が簡明。 なんとなく、typeだとバイナリーファイルは、0x1Aのところでちぎれるかと思ったけど、大丈夫でした。 本文に追記しておきます。
退会済みユーザー

退会済みユーザー

2024/07/15 06:32 編集

近年vbsも廃止する方向に決まっていますし、MS-DOS由来のコマンドやバッチがなくなるとは思っていませんが、いつの日か何かで簡易代替されてもおかしくないと思います。PowerShellは頻繁に変わりすぎたりポリシー関連の環境依存が厄介だったりパフォーマンスが悪かったりで問題も多いですが、クロスプラットフォームに挑戦したりと良い面もあると思います。 なので正直簡単でも簡明とも思えない、初心者には呪文に見えるモノが多く、不完全で説明資料の少ないバッチシステムを私はオススメできません。 あと、細かいですがtypeでリダイレクトするとCtrl+C押したときの異常系などで問題がわかりにくくなります。
otn

2024/07/15 07:58

> タスクスケジューラが設定しているバッチファイルを起動して、 と、もともとの呼び出し元が、バッチファイルなので、バッチファイルで完結すれば簡明です。 一般的なプログラミング言語で書いたほうが適している文字列処理や、ファイルの中味の処理など、あるいはシステム環境設定変更処理を、バッチスクリプトでやれと勧めているわけではなく、「ファイルのコピー」というバッチスクリプトが得意とする分野については、バッチスクリプトでやるのが簡単簡明です。 > なので正直簡単でも簡明とも思えない、初心者には呪文に見えるモノが多く Javaよりもですか?それは賛同者が少なそうです。 > あと、細かいですがtypeでリダイレクトするとCtrl+C押したときの異常系などで問題がわかりにくくなります。 この処理単体としては、Ctrl+Cで中断したら、再実行でOKです。 そもそもが、タスクスケジューラーからの起動なので、あまり手動での中断は無いと思いますが、もし手動での中断があり得て、タスク全体の再実行で駄目な場合は、再実行ポイントをしっかり作っておけば良いだけです。手動での中断だけでなく、エラー終了の場合も同じく。 このあたりは、どの言語を使うのかに依らず必要なことですね。
退会済みユーザー

退会済みユーザー

2024/07/15 08:57

> もともとの呼び出し元が、バッチファイルなので そこがJavaの呼び出しだけであれば簡明ですよね バッチの機能を使ってたら他のOSに持っていくときにそのまま使えません > > なので正直簡単でも簡明とも思えない、初心者には呪文に見えるモノが多く > Javaよりもですか?それは賛同者が少なそうです。 Javaの実装の方が簡便ですよ。バッチはfor文やらdp変数の後ろの記号とか遅延環境変数とかエスケープの仕方など、奇々怪々です。私がそれらを使えないわけではありませんが、メンテナンスする人がそれらを知っていることは少ないです。 後述しますが、ちょっとしたことの意図が伝わらないのも問題ですね。 > > あと、細かいですがtypeでリダイレクトするとCtrl+C押したときの異常系などで問題がわかりにくくなります。 > この処理単体としては、Ctrl+Cで中断したら、再実行でOKです。 だめなんですよ。中断された場合にファイルが残るので。この手の処理は後続の処理があることも多く、ファイルの有無で結果が変わるので、中断してもファイルが残らない方がベターなわけです。残らない方法があるのに残る方法を使っていたら、問題が起きたとき設計/実装不具合に分類されます。 しかしある程度知識のあるotnさんでさえ、やらかしてしまうほどに、実装意図が伝わりにくいのがバッチファイルなどの古い原始的なスクリプト言語なんですよ。COPYと書いた意図が伝わらないわけです。Javaでfiles.copyをInputStreamとOutputStreamで処理しようとしてたら、え?ってなるのですが、スクリプトだとそうならないわけです。慣れてるスクリプトなら、ああそれはコッチの方がいいって気付くものですが、慣れてないと言われないと気付かないケースもあるでしょう。ちなみにCtrl+Cの話は昔私が業務で実際に指摘された類の話ですよ(といっても開発環境でしたが)。
tamanaga

2024/07/15 14:06

otnさん・dameoさん 色々とご教授ありがとうございます。まだまだ細かい部分を知っておらず、少しではありますがこの機会に良い刺激を受けました。やり方に関してはいくつもあります。
tamanaga

2024/07/16 15:13

回答ありがとうございます。 ベストアンサーは別の方を選ばせていただきましたが、こちらの回答も非常に参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問