I'm looking for a way to get a unique file id in a Java application, and came across this:
Unique file identifier in windows
Now, I tried the answer supplied by Ashley Henderson himself (the one that asked the question), and that worked fine in C#. But I need to do this in Java, in order to have the app work across platforms.
Is there any way to port this to Java, or get to the same id some other way?
EDIT:
I almost got it working now, using the solution by eee, only I need it to be in a library, and when I compile it as a library I get an error, even though everything is working fine in a test application with everything included. But with a separate library that I try to import (no compiler errors) I get this runtime error:
debug:
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/jna/Structure
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at winfileid.FileId.getFileId(FileId.java:37)
at testfileid.TestFileId.main(TestFileId.java:19)
Caused by: java.lang.ClassNotFoundException: com.sun.jna.Structure
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 14 more
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
I've included the jna.jar and platform.jar in the library when I compiled it... Please note again that I'm very new to Java, but what am I doing wrong?
Using JNA version 3.3.0:
Kernel32.INSTANCE.GetFileInformationByHandle Test case:
package win.test;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinBase.FILETIME;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import win.test.Kernel32.BY_HANDLE_FILE_INFORMATION;
public class FileTest {
/**
* @param args
*/
public static void main(String[] args) {
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx
final int FILE_SHARE_READ = (0x00000001);
//final int FILE_SHARE_WRITE = (0x00000002);
//final int FILE_SHARE_DELETE = (0x00000004);
final int OPEN_EXISTING = (3);
final int GENERIC_READ = (0x80000000);
//final int GENERIC_WRITE = (0x40000000);
//final int FILE_FLAG_NO_BUFFERING = (0x20000000);
//final int FILE_FLAG_WRITE_THROUGH = (0x80000000);
//final int FILE_READ_ATTRIBUTES = (0x0080);
//final int FILE_WRITE_ATTRIBUTES = (0x0100);
//final int ERROR_INSUFFICIENT_BUFFER = (122);
final int FILE_ATTRIBUTE_ARCHIVE = (0x20);
WinBase.SECURITY_ATTRIBUTES attr = null;
BY_HANDLE_FILE_INFORMATION lpFileInformation = new BY_HANDLE_FILE_INFORMATION();
HANDLE hFile = null;
hFile = Kernel32.INSTANCE.CreateFile(args[0], GENERIC_READ, FILE_SHARE_READ, attr, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, null);
System.out.println("CreateFile last error:" + Kernel32.INSTANCE.GetLastError());
//if (hFile. != -1)
{
win.test.Kernel32.INSTANCE.GetFileInformationByHandle(hFile, lpFileInformation);
System.out.println("CREATION TIME: " + FILETIME.filetimeToDate(lpFileInformation.ftCreationTime.dwHighDateTime, lpFileInformation.ftCreationTime.dwLowDateTime));
System.out.println("VOLUME SERIAL NO.: " + Integer.toHexString(lpFileInformation.dwVolumeSerialNumber.intValue()));
System.out.println("FILE INDEX HIGH: " + lpFileInformation.nFileIndexHigh);
System.out.println("FILE INDEX LOW: " + lpFileInformation.nFileIndexLow);
System.out.println("GetFileInformationByHandle last error:" + Kernel32.INSTANCE.GetLastError());
}
Kernel32.INSTANCE.CloseHandle(hFile);
System.out.println("CloseHandle last error:" + Kernel32.INSTANCE.GetLastError());
}
}
Sample output:
CreateFile last error:0
CREATION TIME: Tue Nov 29 22:24:04 SGT 2011
VOLUME SERIAL NO.: 900c0655
FILE INDEX HIGH: 1769472
FILE INDEX LOW: 286306
GetFileInformationByHandle last error:0
CloseHandle last error:0
Kernel32 JNA instance class:
package win.test;
import java.util.HashMap;
import java.util.Map;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.WinBase.FILETIME;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
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();
/**
typedef struct _BY_HANDLE_FILE_INFORMATION {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD dwVolumeSerialNumber;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD nNumberOfLinks;
DWORD nFileIndexHigh;
DWORD nFileIndexLow;
} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;
*/
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 static class ByReference extends BY_HANDLE_FILE_INFORMATION implements Structure.ByReference {
};
public static class ByValue extends BY_HANDLE_FILE_INFORMATION implements Structure.ByValue {
};
};
/**
BOOL WINAPI GetFileInformationByHandle(
__in HANDLE hFile,
__out LPBY_HANDLE_FILE_INFORMATION lpFileInformation
);
*/
boolean GetFileInformationByHandle(
HANDLE hFile,
BY_HANDLE_FILE_INFORMATION lpFileInformation
);
}
In Java you would need JNI, native C compilation, both for Windows (using the C# code), and for Unix/Linux (using the inode of a file). Honestly I do not think this is very safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With