*タイムスタンプが変わらないファイルを読み込むときの注意 [#nf0c07cd]
レアケースですが、知り合いから相談を受けて調べた結果のメモ。~
InputStreamはどうやらファイルをキャッシュするらしく、タイムスタンプが変わらず内容だけ変わる場合だと、変更前のファイルの内容を返してくれます。~
以下のソースを実行してみると、それがわかります。~
#codeprettify{{
package test.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopyTest {
public static void main(String[] args){
File f = null;
f = new File("./test.txt");
fileOut(f, "ABC");
fileRead(f);
f = new File("./test.txt");
fileOut(f, "EFG");
fileRead(f);
}
private static void fileRead(File f){
FileInputStream fis = null;
byte[] buff = new byte[(int)f.length()];
try {
fis = new FileInputStream(f);
fis.read(buff);
System.out.println(new String(buff));
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
private static void fileOut(File f, String data){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
f.setLastModified(0);
}
}
}}
このソースの実行結果は
ABC
ABC
と出てきます。~
じゃぁ、どうしようかという話になりますが、最終更新日を操作することで、読み込みが可能となります。
#codeprettify{{
package test.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopyTest {
public static void main(String[] args){
File f = null;
f = new File("./test.txt");
fileOut(f, "ABC");
fileRead(f);
f = new File("./test.txt");
fileOut(f, "EFG");
fileRead(f);
}
private static void fileRead(File f){
FileInputStream fis = null;
byte[] buff = new byte[(int)f.length()];
long l = f.lastModified();
f.setLastModified(l + 1);
try {
fis = new FileInputStream(f);
fis.read(buff);
System.out.println(new String(buff));
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
f.setLastModified(l);
}
private static void fileOut(File f, String data){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
f.setLastModified(0);
}
}
}}
何やってるかというと、
+ファイルを読み込む前に、ファイルの最終更新日をlastModified()メソッドで取得
+取得した最終更新日に1を加算
+ファイルを読み込む
+最終更新日を元に戻す
実行結果は
ABC
EFG
となります。~
この方法がいいか悪いかわかりませんが、このようなケースに遭遇した場合にはいいかもしれません。