Im trying to implement file synchronization in conjunction with java.nio watchevent. Though, as known and discussed in other posts, it doesnt handle renames and moves. I tried out jpathwatch which didnt really seem to cover the scenarios i needed so i try to get unique object identifiers thus being able to track these events myself.
The problem i have is that i tried implement BY_HANDLE_FILE_INFORMATION using JNA and it worked fine for files. But i get null return and error 6 when i try to access directories this way. So what im trying to ascertain is the best way to get a trackable id for both files and folders. If ive made some error, i have som issue locally or with eclipse, or if i perhaps need to look elsewhere for this information.
My testcode is as follows:
@Override
public String getUniqueFileId(Path file) {
BY_HANDLE_FILE_INFORMATION nfo = new BY_HANDLE_FILE_INFORMATION();
HANDLE handle = com.sun.jna.platform.win32.Kernel32.INSTANCE.CreateFile(file.toString(), 0x80000000, 0x00000001, null, 3, 0x80, null);
if(Kernel32.INSTANCE.GetLastError() != 0) {
LOGGER.error("Error occured for '" + file.toString() + "' (Error " + Kernel32.INSTANCE.GetLastError() + ")");
}
Kernel32.INSTANCE.GetFileInformationByHandle(handle, nfo);
if(Kernel32.INSTANCE.GetLastError() != 0) {
LOGGER.error("Error occured for '" + file.toString() + "' (Error " + Kernel32.INSTANCE.GetLastError() + ")");
}
String identifier = nfo.nFileIndexHigh + nfo.nFileIndexLow.toString() + Integer.toHexString(nfo.dwVolumeSerialNumber.intValue());
com.sun.jna.platform.win32.Kernel32.INSTANCE.CloseHandle(handle);
return identifier;
}
And:
public interface Kernel32 extends StdCallLibrary {
final static Map<String, Object> WIN32API_OPTIONS = new HashMap<String, Object>() {
private static final long serialVersionUID = 1L;
{
put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
}
};
public Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("Kernel32", Kernel32.class, WIN32API_OPTIONS);
public int GetLastError();
public class BY_HANDLE_FILE_INFORMATION extends Structure {
public DWORD dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public DWORD dwVolumeSerialNumber;
public DWORD nFileSizeHigh;
public DWORD nFileSizeLow;
public DWORD nNumberOfLinks;
public DWORD nFileIndexHigh;
public DWORD nFileIndexLow;
public List<String> getFieldOrder() {
return Arrays.asList(new String[] {
"dwFileAttributes",
"ftCreationTime",
"ftLastAccessTime",
"ftLastWriteTime",
"dwVolumeSerialNumber",
"nFileSizeHigh",
"nFileSizeLow",
"nNumberOfLinks",
"nFileIndexHigh",
"nFileIndexLow"
});
};
};
boolean GetFileInformationByHandle(HANDLE hFile, BY_HANDLE_FILE_INFORMATION lpFileInformation);
}
If someone spots any problem or could give me a push in the right direction i would be greatful.
Im using Wondows 10 / Eclipse but had same issue on Windows 8.
UPDATE: realized i called the getlasterror to late, but updated the code and it gives med first error 5, then error 6. Error 5 indicate permission issue, but full permission for all users and running eclipse in administrator mode unfortunately didnt help. All files work fine, no folder work.