Je cherche un moyen d'obtenir un identifiant de fichier unique dans une application Java et je suis venu sur ceci:
Identificateur de fichier unique dans Windows P>
Maintenant, j'ai essayé la réponse fournie par Ashley Henderson lui-même (celle qui a posé la question), et cela a fonctionné bien en C #. Mais je dois le faire en Java, afin de faire fonctionner l'application sur toutes les plateformes. P>
existe-t-il un moyen de le porter à Java ou d'arriver à la même identité d'une autre manière? P>
EDIT: P>
Je l'ai presque travaillé maintenant, en utilisant la solution par EEE, j'en ai besoin que j'en ai besoin pour être dans une bibliothèque, et quand je le compile comme une bibliothèque, je reçois une erreur, même si Tout fonctionne bien dans une application de test avec tout inclus. Mais avec une bibliothèque distincte que j'essaie d'importer (aucune erreur de compilateur), j'obtiens cette erreur d'exécution: p> J'ai inclus le JNA.jar et la plate-forme.jar dans le Bibliothèque quand je l'ai compilée ... S'il vous plaît noter à nouveau que je suis très nouveau à Java, mais qu'est-ce que je fais mal? p> p>
4 Réponses :
Impossible d'utiliser le chemin de fichier comme identifiant unique ?! p>
Le chemin de fichier complet est assez unique ... p>
Oui, c'est unique - mais il n'est pas préservé lorsque vous déplacez un fichier dans un autre répertoire, ce qui semble être l'intention de l'ID de fichier.
Droite, le point est de pouvoir déplacer les fichiers autour et renommez-les librement, de sorte que les chemins de fichiers sont en réalité ce que j'ai besoin de découvrir après de tels mouvements ou renommés.
En Java, vous auriez besoin de la compilation JNI, de Native C, à la fois pour Windows (à l'aide du code C #) et pour UNIX / Linux (à l'aide de l'INODE d'un fichier). Honnêtement, je ne pense pas que cela soit très sûr. P>
+1 Le système de fichiers utilisé est également important, ce qui rend la portabilité plus difficile - bonne chance sur la graisse, par exemple :)
Oui, j'ai regardé brièvement cela et j'espérais qu'il y aurait un moyen plus simple. Mais j'espérais ne pas avoir à la compiler et l'utiliser comme c'est en Java, mais plutôt s'il y avait un moyen de le réécrire à Java pour accéder au même ID ... Obtenir un identifiant de fichier dans * Nix est beaucoup plus simple, Mais je ne trouve pas un moyen de le faire pour les fenêtres sauf cet exemple en C #. BTW, la graisse n'est pas un problème. Il va être NTFS sous Windows et Mac OS X est l'autre système d'exploitation que je dois envisager.
Utilisation de la version 3.3.0:
Kernel32.Instance.gefileInformation Boîtier de test: 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 ); }
Wow, merci pour cette réponse détaillée ...! Comme je l'ai mentionné, cependant, c'est un peu au-dessus de ma tête et je suis complètement nouveau à Java pour démarrer, n'ayant programmé que dans C # avant. Mais je dois essayer cela maintenant que vous avez fourni un exemple aussi détaillé ... mais je ne comprends pas où vous spécifiez le fichier à vérifier? C'est probablement là-bas, mais il est difficile pour moi de décoder cela. De plus, quel est l'index de fichier haute vs fichier fichier bas? Dans l'exemple que j'ai utilisé (à partir du lien), il n'y avait qu'une seule valeur d'indice, alors que dois-je utiliser ici pour identifier le fichier?
BTW, puisque JNA semble être pour accéder au code natif dans les DLL, il n'ya pas de moyen de le faire simplement en compilant le code dans l'exemple de lien (que j'ai déjà déjà dans le travail C #) dans une DLL, puis appelez cela avec JNA? Si c'est que j'apprécierais vraiment un exemple simple ... J'espérais que cela pourrait être plus simple.
@Anderssvensson Oui, vous pouvez le faire, mais il est un peu difficile depuis que vous commencez par C # DLL plutôt que C / C ++ DLL que ce dernier est la convention d'appel de la DLL préférée dans la JNA. Vous devez d'abord envelopper votre dll C / c # ++ avant de pouvoir l'utiliser avec JNA. C'est ce que je peux comprendre avec JNA.
@Anderssvensson oh, args [0] code> est à partir de l'argument de commande de programme que vous devez transmettre au programme; Par exemple:
FileTest "test.txt" code> où
"test.txt" code> sera la valeur de
args [0] code> de
de
code> programme
@Anderssvensson Pour exécuter le programme avec succès, vous devez télécharger une bibliothèque de plate-forme JNA ( jna.jar code> et
plateforme.jar code>), ajoutez-les comme des bibliothèques référencées et définissez la propriété système < code> -djna.library.path =
@Anderssvensson Reportez-vous au lien MSDN à la structure by_handle_file_information code>, il est indiqué que,
L'identifiant (pièces basses et hautes) et le numéro de série du volume identifient de manière unique un fichier sur un seul ordinateur. Pour déterminer si deux poignées ouvertes représentent le même fichier, combinez l'identifiant et le numéro de série de volume pour chaque fichier et les comparez. Code> Link
Merci, mais j'obtiens une exception de compilateur pour l'importation Win32.wininnet.kernel32.By_Handle_File_Information; Il dit que cela n'existe pas et, en fait, je n'ai aucune idée d'où cela en tirerait. J'ai lu sur la page Web de la JNA que la JNA veillerait à charger les bibliothèques indigènes elle-même, mais je reçois néanmoins l'erreur, tant dans l'IDE que lorsque j'essaie d'exécuter le programme ...
@Anderssvensson Oh, désolé c'est mon erreur lors de la modification du nom du paquet. "win32.wininnet" devrait être "win.test". Je vais rectifier l'erreur dans les codes ci-dessus ..
Merci! Vous avez travaillé maintenant dans une demande de test. Ceci est une superbe réponse, et je vais vous créditer à coup sûr, mais une dernière question, s'il vous plaît voir mon édition sur le fait de l'obtenir pour travailler dans une bibliothèque distincte pour importer ...
Il peut y avoir plusieurs chemins dans le même fichier via des volumes montés et divers types de liens / points de reparse. L'API unique ID de fichier est la seule façon de déterminer si les multiples chemins à un fichier apparemment identique se réfèrent à des fichiers uniques ou au même fichier via différents chemins. P>
Cela étant dit, je conviens que la seule façon générique Java impliquerait CO ou C ++ Code et JNI. Fait à droite, bien que cela puisse probablement fournir des solutions qui fonctionnent sur Linux et Windows à l'aide de différentes bibliothèques de back-end avec une présentation commune à l'hébergement Code Java. P>
Je soupçonne que vous devriez utiliser JNI pour l'obtenir. Pourquoi voudriez-vous ces informations quand même?
Quel est le cas d'utilisation - pourquoi avez-vous besoin de l'identifiant unique?
Le cas d'utilisation consiste à garder une trace des fichiers lorsqu'ils sont déplacés ou renommés, pour préserver les liens d'autres fichiers.
@Anderssvensson depuis votre dernière modification utilise ma solution, elle doit indiquer que dans votre édition. Sinon, tout le monde peut se confondre avec elle. À propos de l'erreur d'exception, avez-vous été compilée à l'aide d'Eclipse / NetBean IDE ou de la compiler à partir de la ligne de commande? Cela aidera à résoudre le problème ...
Droite, désolé, la modifiée pour indiquer que l'édition est basée sur votre solution. J'ai compilé avec Netbeans.
Avez-vous ajouté la propriété système
-djna.library.path =. \ Lib code> dans virguments VM si vous mettez
jna.jar code> et
plate-forme.jar code> Dans le dossier
lib code> de votre racine de projet? Je soupçonne que votre pot d'application construit n'a pas pu trouver ces pots du dossier LIB de votre construction
@eee Ok, merci, je vais essayer ça. Dans tous les cas, l'application fonctionne bien maintenant avec le code intégré et si je ne reçois pas la bibliothèque de travailler, c'est bien. Alors merci encore, je vais marquer cela comme répondu maintenant!