2011-11-29 37 views
6

Tôi đang tìm kiếm một cách để có được một id tập tin duy nhất trong một ứng dụng Java, và tình cờ gặp này:Nhận id tệp duy nhất trong Windows bằng Java?

Unique file identifier in windows

Bây giờ, tôi đã cố gắng câu trả lời cung cấp bởi Ashley Henderson mình (một trong đó yêu cầu câu hỏi), và điều đó làm việc tốt trong C#. Nhưng tôi cần phải làm điều này trong Java, để ứng dụng hoạt động trên nhiều nền tảng.

Có cách nào để chuyển mã này sang Java hoặc truy cập cùng một id theo cách khác không?

EDIT:

Tôi gần như đã nhận nó làm việc bây giờ, bằng cách sử dụng giải pháp của eee, duy nhất tôi cần nó để được trong thư viện, và khi tôi biên dịch nó như là một thư viện tôi nhận được một lỗi, mặc dù tất cả mọi thứ là làm việc tốt trong một ứng dụng thử nghiệm với tất cả mọi thứ bao gồm. Nhưng với một thư viện riêng biệt mà tôi cố gắng nhập (không có lỗi biên dịch) Tôi nhận được lỗi runtime này:

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) 

Tôi đã bao gồm jna.jar và platform.jar trong thư viện khi tôi biên soạn nó ... Xin lưu ý một lần nữa rằng tôi rất mới với Java, nhưng tôi đang làm gì sai?

+1

Tôi nghi ngờ bạn sẽ phải sử dụng JNI để có được nó. Tại sao bạn muốn thông tin này anyways? – jontro

+0

trường hợp sử dụng là gì - tại sao bạn cần id duy nhất? – aishwarya

+0

Trường hợp sử dụng là theo dõi các tệp khi chúng được di chuyển hoặc đổi tên, để duy trì liên kết từ các tệp khác. – Anders

Trả lời

4

Sử dụng JNA phiên bản 3.3.0:

Kernel32.INSTANCE.GetFileInformationByHandle Kiểm tra trường hợp: sản lượng

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()); 

    } 

} 

mẫu:

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 dụ lớp:

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 
      ); 
} 
+0

Wow, cảm ơn câu trả lời chi tiết đó ...! Như tôi đã đề cập, mặc dù, đây là một chút trên đầu của tôi, và tôi hoàn toàn mới để Java khởi động, chỉ có lập trình trong C# trước đây. Nhưng tôi phải cung cấp cho một thử ngay bây giờ mà bạn cung cấp một ví dụ chi tiết như vậy ... Nhưng tôi không hiểu nơi bạn chỉ định các tập tin được kiểm tra? Nó có thể ở trong đó, nhưng thật khó để tôi giải mã nó. Ngoài ra, FILE INDEX HIGH vs FILE INDEX LOW là gì? Trong ví dụ tôi đã sử dụng (từ liên kết) chỉ có một giá trị chỉ mục, vì vậy tôi nên sử dụng giá trị nào ở đây để xác định tệp? – Anders

+0

BTW, vì JNA có vẻ là để truy cập mã nguồn gốc trong dll, nên không có cách nào để làm điều này đơn giản bằng cách biên dịch mã trong liên kết ví dụ (mà tôi đã có trong C# làm việc) thành một dll, và sau đó gọi với JNA? Nếu đó là tôi thực sự sẽ đánh giá cao một ví dụ đơn giản ... Tôi chỉ hy vọng rằng có thể đơn giản hơn. – Anders

+0

@AndersSvensson có, bạn có thể làm điều đó nhưng nó là một chút khó khăn kể từ khi bạn bắt đầu với C# DLL chứ không phải là C/C + + DLL mà sau này là yêu thích gọi DLL ước trong JNA. Bạn cần phải bọc C# DLL của bạn vào C/C++ DLL trước khi bạn có thể sử dụng nó với JNA. Đó là những gì tôi có thể hiểu được với JNA. – ecle

0

Bạn không thể sử dụng đường dẫn tệp làm id duy nhất của nó?!

đường dẫn tập tin đầy đủ là đủ độc đáo ...

+3

Có, nó là duy nhất - nhưng nó không được lưu giữ khi bạn di chuyển một tệp đến một thư mục khác, mà dường như là ý định đằng sau ID tệp. –

+0

Phải, điểm là có thể di chuyển các tập tin xung quanh và đổi tên chúng một cách tự do, do đó, đường dẫn tập tin thực sự là những gì tôi cần phải tìm ra sau khi di chuyển hoặc đổi tên. – Anders

1

Trong Java bạn sẽ cần JNI, C biên soạn bản xứ, cả hai dành cho Windows (sử dụng mã C#), và cho Unix/Linux (sử dụng inode của một tập tin). Thành thật mà nói tôi không nghĩ rằng điều này là rất an toàn.

+0

+1 Hệ thống tập tin đang sử dụng cũng rất quan trọng, làm cho việc di chuyển khó khăn hơn - may mắn về FAT, ví dụ :) –

+0

Vâng, tôi đã xem xét ngắn gọn điều đó và hy vọng sẽ có một cách đơn giản hơn. Nhưng tôi đã hy vọng không phải biên dịch điều này và sử dụng nó như trong Java, mà đúng hơn là nếu có cách viết lại nó trong Java để nhận được cùng một id ... Lấy một tập tin id trong * nix đơn giản hơn rất nhiều, nhưng tôi không thể tìm thấy một cách để làm điều đó cho Windows, ngoại trừ ví dụ này trong C#. BTW, FAT không phải là một vấn đề. Nó sẽ là NTFS trong Windows, và Mac OS X là hệ điều hành khác mà tôi cần phải xem xét. – Anders

+0

xem giải pháp JNA của tôi – ecle

Các vấn đề liên quan