概要
Javaからjcifsというライブラリを使ってWindows共有ファイルにアクセスしたとき、最終更新時間や作成時間の情報がうまく取れなかった問題に関するメモ。
バージョン情報
pom.xml
<dependency>
<groupId>jcifs</groupId>
<artifactId>jcifs</artifactId>
<version>1.3.17</version>
</dependency>
現象
jcifs.smb.SmbFile#lastModified
とjcifs.smb.SmbFile#createTime
が0
を返す場合がある. 正しい値を返す場合もある.
解決方法
jcifs.smb.SmbFile
のコンストラクタを呼び出す前に,
java
jcifs.Config.setProperty("jcifs.smb.client.attrExpirationPeriod", "0");
をどこかで呼び出す(jcifs.Configはjcifsのstaticな設定です).
詳細
lastModified()
および, このメソッドが呼び出しているexists()
のソースを追うと原因が分かります.
-
lastModified()
はexists()
を呼び出したあと, フィールドlastModified
の値を返しています. -
exists()
の中にはフィールドlastModified
を更新する処理がありますが, フィールドattrExpiration
の値がSystem.currentTimeMillis()
の返り値よりも大きい場合はこの処理をスキップします. -
lastModified
はインスタンス生成時に(コンストラクタによっては)初期値が0
にセットされています. -
attrExpiration
はインスタンス生成時にSystem.currentTimeMillis() + attrExpirationPeriod
の値がセットされています. - フィールド
attrExpirationPeriod
の値はDEFAULT_ATTR_EXPIRATION_PERIOD
によってデフォルト値5000
が設定されています.
つまりは更新時間情報のキャッシュ処理が原因! SmbFile
はインスタンス生成されてから5000ミリ秒経つまではlastModified()
で0
を返し続けます. attrExpirationPeriod
をデフォルト値5000
を参照させず0
を指定してあげればよいので, jcifs.Config
で"jcifs.smb.client.attrExpirationPeriod"
に0
を設定すると, この問題は解決します.