Ответ, найденный коллегой, следующий: Используя Java Native Access Framework (https://github.com/java-native-access/jna), можно использовать Win-API для получения правильной блокировки.
Это получает дескриптор с эксклюзивной блокировкой записи с общим доступом:
WinNT.HANDLE lockFile = Kernel32.INSTANCE.CreateFile(filename,
WinNT.GENERIC_READ | WinNT.GENERIC_WRITE,
WinNT.FILE_SHARE_READ,
null,
WinNT.OPEN_ALWAYS,
WinNT.FILE_ATTRIBUTE_NORMAL,
null);
И следующее освобождает блокировку:
Kernel32.INSTANCE.CloseHandle(lock);
Для чтения содержимого Kernel32.INSTANCE.ReadFile может быть используется и для записи Kernel32.INSTANCE.WriteFile.
Поскольку JNA по умолчанию отсутствует GetFileSizeEx, SetFilePointer и SetEndOfFile, этот интерфейс можно использовать для доступа к этим методам для повышения качества жизни при записи и чтении файла:
package filesystem.jna;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public interface JnaFileAccess extends StdCallLibrary {
JnaFileAccess INSTANCE = Native.load("kernel32", JnaFileAccess.class, W32APIOptions.DEFAULT_OPTIONS);
boolean GetFileSizeEx(WinNT.HANDLE fileHandle, LongByReference size);
int SetFilePointer(WinNT.HANDLE fileHandle, long DistanceToMove, Pointer DistanceToMoveHigh, int MoveMethod);
boolean SetEndOfFile(WinNT.HANDLE fileHandle);
}
Вызовы могут быть выполнены следующим образом:
Установить курсор на начало файла:
JnaFileAccess.INSTANCE.SetFilePointer(fileHandle, 0, null, 0);
Записать данные, а затем установить конец файла:
JnaFileAccess.INSTANCE.SetEndOfFile(fileHandle);
Для этого ничего не требуется, кроме интерфейса, он сопоставляется с Win-API