-: = ИЗМЕНИТЬ УПРОЩЕНИЕ =: -
Я столкнулся с проблемой в процессе переноса кода из среды Linux (Ubuntu LTS 12.4) в Windows Server 2008.
Мне нужно использовать файл с отображением памяти, но я не могу предотвратить ошибку ниже в Windows.
Эта проблема воспроизводится в unit test ниже. 2 теста преуспевают в Linux, но в Windows тест testWithRandowmAccessFile терпит неудачу с трассировкой стека внизу.
В чем заключается основная причина теста testWithRandowmAccessFile?
Как я должен реализовать это в 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);
}
}
добавление трассировки латинского ввода, которую я получаю при запуске unit test из командной строки на окнах.
There was 1 failure:
1) testWithRandowmAccessFile(TestIOOnWindows) java.nio.file.FileSystemException: C:\Users\Administrator\AppData\Local\Temp\manipulated.txt -> C:\Users\Administrator\AppData\Local\Temp\target.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