-:= EDITED TO SIMPLIFY =:-
I am facing an issue in the process of porting code from a Linux (Ubuntu LTS 12.4) environment to Windows Server 2008.
I need to use memory mapped file but I am not able to prevent the error below on Windows.
This issue is reproduced in the unit test below. The 2 tests are succeeding on Linux but on Windows the test testWithRandowmAccessFile fails with the stack trace on the bottom.
What is the root cause of the testWithRandowmAccessFile test failing?
How am I supposed to implement that on Windows?
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
public class TestIOOnWindows {
@Test
public void testWithRandowmAccessFile() throws IOException {
final File sourceFile = new File("source.txt");
final File manipulatedFile = new File("manipulated.txt");
final File targetFile = new File("target.txt");
try
(
FileInputStream sourceInputStream = new FileInputStream(sourceFile);
RandomAccessFile manipulated = new RandomAccessFile(manipulatedFile, "rw");
FileChannel fcOut = manipulated.getChannel()
)
{
byte[] sourceBytes = new byte[Long.valueOf(sourceFile.length()).intValue()];
IOUtils.read(sourceInputStream, sourceBytes);
final int length = sourceBytes.length;
// ========= with this single line on Windows, the move fails ======
MappedByteBuffer byteBuffer = fcOut.map(FileChannel.MapMode.READ_WRITE, 0, length);
// commenting this line would not prevent the error on Windows
byteBuffer.put(sourceBytes, 0, length);
}
Files.move(
Paths.get(manipulatedFile.getAbsolutePath()),
Paths.get(targetFile.getAbsolutePath()),
StandardCopyOption.REPLACE_EXISTING);
}
@Test
public void testWithFileOutputStream() throws IOException {
final File sourceFile = new File("source.txt");
final File manipulatedFile = new File("manipulated.txt");
final File targetFile = new File("target.txt");
try
(
FileInputStream sourceInputStream = new FileInputStream(sourceFile);
FileOutputStream manipulatedOutputStream = new FileOutputStream(manipulatedFile);
FileChannel fcIn = sourceInputStream.getChannel();
FileChannel fcOut = manipulatedOutputStream.getChannel()
)
{
final long length = sourceFile.length();
// ========= with this single line on Windows, the move succeed ====
fcIn.transferTo(0, length, fcOut);
}
Files.move(
Paths.get(manipulatedFile.getAbsolutePath()),
Paths.get(targetFile.getAbsolutePath()),
StandardCopyOption.REPLACE_EXISTING);
}
}
adding the tack trace I am getting when running the unit test from command prompt on windows.
There was 1 failure:
1) testWithRandowmAccessFile(TestIOOnWindows) java.nio.file.FileSystemException: C:UsersAdministratorAppDataLocalTempmanipulated.txt -> C:UsersAdministratorAppDataLocalTemparget.txt: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileCopy.move(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.move(Unknown Source)
at java.nio.file.Files.move(Unknown Source)
===> at TestIOOnWindows.testWithRandowmAccessFile(TestIOOnWindows.java:40) <===
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
FAILURES!!!
Tests run: 2, Failures: 1
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…