Java临时文件测试在OSX上传递,在Windows上失败

时间:2013-11-01 16:29:46

标签: java junit io cross-platform

我有一个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}}

任何想法的家伙?感谢。

1 个答案:

答案 0 :(得分:0)

该问题与Windows和Unix处理文件锁定的方式之间的差异有关。在Unix上,一个进程可以写入文件,另一个进程可以打开它来读取它。 Windows不允许这样做。

完全披露:如果Java无法在文件上执行IO类型的东西,我希望Java抛出IOException,暂时忘记其中许多操作返回布尔值,指明操作是否成功。

长话短说,在updateValueForKey()的末尾,我删除_file,并将tmp重命名为_file,temp仍然有一个FileWriter打开它,而_file仍然有一个BufferedReader打开它。基本上,我不得不在finally块下面移动_file.delete和temp.renameTo()。