зеркало из https://github.com/mono/ikvm-fork.git
Implemented atomic file move (on Windows).
This commit is contained in:
Родитель
b720ca0eaa
Коммит
5178e7cb0b
|
@ -36,6 +36,8 @@ import cli.System.IO.FileMode;
|
|||
import cli.System.IO.FileShare;
|
||||
import cli.System.IO.FileStream;
|
||||
import cli.System.IO.FileOptions;
|
||||
import cli.System.Runtime.InteropServices.DllImportAttribute;
|
||||
import cli.System.Runtime.InteropServices.Marshal;
|
||||
import cli.System.Security.AccessControl.FileSystemRights;
|
||||
import com.sun.nio.file.ExtendedOpenOption;
|
||||
import java.io.FileDescriptor;
|
||||
|
@ -628,6 +630,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
|
|||
NetPath nsource = NetPath.from(source);
|
||||
NetPath ntarget = NetPath.from(target);
|
||||
boolean overwrite = false;
|
||||
boolean atomicMove = false;
|
||||
for (CopyOption opt : options)
|
||||
{
|
||||
if (opt == StandardCopyOption.REPLACE_EXISTING)
|
||||
|
@ -636,7 +639,14 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
|
|||
}
|
||||
else if (opt == StandardCopyOption.ATOMIC_MOVE)
|
||||
{
|
||||
throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option");
|
||||
if (WINDOWS)
|
||||
{
|
||||
atomicMove = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -651,6 +661,36 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
|
|||
sm.checkRead(nsource.path);
|
||||
sm.checkWrite(ntarget.path);
|
||||
}
|
||||
if (atomicMove)
|
||||
{
|
||||
int MOVEFILE_REPLACE_EXISTING = 1;
|
||||
if (MoveFileEx(nsource.path, ntarget.path, MOVEFILE_REPLACE_EXISTING) == 0)
|
||||
{
|
||||
final int ERROR_FILE_NOT_FOUND = 2;
|
||||
final int ERROR_PATH_NOT_FOUND = 3;
|
||||
final int ERROR_ACCESS_DENIED = 5;
|
||||
final int ERROR_NOT_SAME_DEVICE = 17;
|
||||
final int ERROR_FILE_EXISTS = 80;
|
||||
final int ERROR_ALREADY_EXISTS = 183;
|
||||
int lastError = Marshal.GetLastWin32Error();
|
||||
switch (lastError)
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
throw new NoSuchFileException(nsource.path, ntarget.path, null);
|
||||
case ERROR_ACCESS_DENIED:
|
||||
throw new AccessDeniedException(nsource.path, ntarget.path, null);
|
||||
case ERROR_NOT_SAME_DEVICE:
|
||||
throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option");
|
||||
case ERROR_FILE_EXISTS:
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
throw new FileAlreadyExistsException(nsource.path, ntarget.path, null);
|
||||
default:
|
||||
throw new FileSystemException(nsource.path, ntarget.path, "Error " + lastError);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (false) throw new cli.System.ArgumentException();
|
||||
|
@ -711,6 +751,9 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider
|
|||
}
|
||||
}
|
||||
|
||||
@DllImportAttribute.Annotation(value="kernel32", SetLastError=true)
|
||||
private static native int MoveFileEx(String lpExistingFileName, String lpNewFileName, int dwFlags);
|
||||
|
||||
public boolean isSameFile(Path path, Path path2) throws IOException
|
||||
{
|
||||
if (path.equals(path2))
|
||||
|
|
Загрузка…
Ссылка в новой задаче