我有一个JUnit测试,它测试我正在使用的一段代码,它使用临时文件来执行某些功能。无论出于何种原因,测试都会在OSX上传递,但在Windows 7上失败。为简化起见,我将测试复制到一个新文件中,然后将其煮沸,尽可能简单,同时仍然显示错误。
基本上,我通过将逗号分隔的键值对写入文件来初始化临时文件(然后断言它存在,它确实存在)。然后,我尝试根据键替换该行的值。 updateValueForKey()
具有布尔值“checkOldVal”,如果为true,则要求传入的oldVal
与文件中的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上失败,并传递OSX,无论这是真还是假
Windows Java版本:1.6.0_45
OSX Java版本:1.6.0_65
代码如下:
{{1}}
任何想法的家伙?感谢。
答案 0 :(得分:0)
该问题与Windows和Unix处理文件锁定的方式之间的差异有关。在Unix上,一个进程可以写入文件,另一个进程可以打开它来读取它。 Windows不允许这样做。
完全披露:如果Java无法在文件上执行IO类型的东西,我希望Java抛出IOException,暂时忘记其中许多操作返回布尔值,指明操作是否成功。
长话短说,在updateValueForKey()的末尾,我删除_file,并将tmp重命名为_file,temp仍然有一个FileWriter打开它,而_file仍然有一个BufferedReader打开它。基本上,我不得不在finally块下面移动_file.delete和temp.renameTo()。