[英]Java Temporary File test passes on OSX, fails on Windows
我已經進行了一個JUnit測試,該測試測試了我一直在使用臨時文件執行某些功能的一段代碼。 出於某種原因,該測試在OSX上通過,但在Windows 7上失敗。為簡化起見,我將測試復制到了一個新文件中,並將其簡化為盡可能簡單,同時仍然顯示了錯誤。
基本上,我通過將逗號分隔的鍵/值對寫入臨時文件來初始化臨時文件(然后斷言它確實存在)。 然后,我嘗試根據鍵替換該行的值。 updateValueForKey()
具有布爾值“ checkOldVal”,如果為true,則要求傳入的oldVal
與文件中的oldVal
相匹配。 此測試在Windows上失敗,並且在OSX上通過,無論這是對還是錯
Windows Java版本:1.6.0_45
OSX Java版本:1.6.0_65
代碼如下:
public class SimpleTempFileTest {
ReadWriteLock _fileLock = null;
File _file = null;
public SimpleTempFileTest() {
}
@Test
public void simpleTempFileTest() throws Exception {
_file = File.createTempFile("testCsv", null);
_file.deleteOnExit();
_fileLock = new ReentrantReadWriteLock();
BufferedWriter writer = null;
try {
_fileLock.writeLock().lock();
writer = new BufferedWriter(new FileWriter(_file, true));
writer.append("foo,bar");
writer.newLine();
} finally {
if (writer != null) {
writer.close();
}
_fileLock.writeLock().unlock();
}
BufferedReader br = new BufferedReader(new FileReader(_file));
String line = br.readLine();
assertTrue("Unexpected value. Line=" + line, line.equals("foo,bar"));
assertTrue("Unexpected value. Line=" + line, br.readLine() == null);
br.close();
//Fails whether checkOldVal is true or false
updateValueForKey("foo", "bar", "baz", true);
br = new BufferedReader(new FileReader(_file));
line = br.readLine();
//Everything up to this point passes, but the following assertion fails
assertTrue("Unexpected value. Line=" + line, line.equals("foo,baz"));
assertTrue("Unexpected value. Line=" + line, br.readLine() == null);
br.close();
}
String updateValueForKey(String key, String oldVal, String newVal, boolean checkOldVal) throws FileNotFoundException, IOException {
BufferedReader br = null;
BufferedWriter writer = null;
File temp = null;
try {
_fileLock.writeLock().lock();
br = new BufferedReader(new FileReader(_file));
temp = File.createTempFile("csvTmp", ".tmp");
writer = new BufferedWriter(new FileWriter(temp, true));
boolean seek = true;
String line;
while ((line = br.readLine()) != null) {
if (seek) {
String[] nvp = line.split(",");
System.out.println("nvp[0]=" + nvp[0] + ", nvp[1]=" + nvp[1]);
if (nvp[0].equalsIgnoreCase(key)) {
if (nvp[1].equals(oldVal) || !checkOldVal) {
String lineToWrite = key + "," + newVal;
System.out.println("Writing " + lineToWrite);
writer.write(lineToWrite);
writer.newLine();
seek = false;
continue;
} else {
System.out.println("Failed for " + key + ". Val incorrect.");
return "Password incorrect";
}
}
}
writer.write(line);
writer.newLine();
}
_file.delete();
temp.renameTo(_file);
return null;
} finally {
if (br != null) {
br.close();
}
if (writer != null) {
writer.close();
}
if (temp != null) {
temp.delete();
}
_fileLock.writeLock().unlock();
}
}
}
有想法嗎? 謝謝。
該問題與Windows和Unix處理文件鎖定的方式之間的差異有關。 在Unix上,一個進程可以寫入文件,而另一個可以打開該文件以讀取它。 Windows不允許這樣做。
完全公開:我希望Java如果無法在文件上執行IO類型的操作,則將引發IOException,從而短暫地忘記了其中許多操作都返回布爾值,指定該操作是否成功。
長話短說,在updateValueForKey()的結尾處,我刪除_file,並將tmp重命名為_file,temp仍然針對它打開FileWriter,_file仍然針對它打開BufferedReader。 基本上,我必須將_file.delete和temp.renameTo()移動到finally塊下方。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.