2009-04-10 3 views
1

Die Fakten bewegt:Wie Sie feststellen, ob eine Datei logisch verschoben werden oder physikalisch

Wenn eine Datei verschoben wird, gibt es zwei Möglichkeiten:

  1. Die Quell- und Zieldatei auf dem gleichen Partition und nur der Dateisystemindex ist aktualisiert
  2. Die Quelle und das Ziel sind auf zwei verschiedenen Dateisystem und die Datei muss Byte pro Byte verschoben werden. (Kopieren aka auf move)

Die Frage:

Wie kann ich feststellen, ob eine Datei entweder logisch oder physikalisch bewegt wird?

Ich übertrage große Dateien (700+ MBS) und würde ein anderes Verhalten für jede Situation annehmen.


Edit:

ich bereits einen bewegten Datei-Dialog mit einem Arbeitsthread codiert habe, dass die Blockierung io ausführen rufen Sie die Datei einen meg zu einem Zeitpunkt, zu kopieren. Es liefert dem Benutzer Informationen wie eine grobe Schätzung der verbleibenden Zeit und Übertragungsrate.

Das Problem ist: Woher weiß ich, ob die Datei logisch verschoben werden kann, bevor Sie versuchen, es physisch zu verschieben?

+0

Sie machen die falsche Annahme, dass eine Datei bewegen sich auf derselben Partition ist lediglich eine Änderung der Metadaten. Dies gilt nicht unbedingt für NTFS. Wenn Sie eine Datei in ein komprimiertes Verzeichnis ein- oder auslagern, kann eine physische Kopie die Datei (de) komprimieren. In ähnlicher Weise können verschlüsselte Verzeichnisse dazu führen, dass physische Kopien die Datei (de) kryptieren. – MSalters

+0

Sie haben Recht, ein Kopier-/Löschvorgang kann innerhalb derselben NTFS-Partition erforderlich sein. Mein Ziel war es jedoch, festzustellen, ob eine Kopie/Löschung erforderlich ist oder ob eine einfache Änderung der Metadaten die Aufgabe übernehmen würde, die Datei zu verschieben. Die akzeptierte Lösung behebt dieses Problem. Wenn Sie andere Fragen oder andere Lösungen haben, können Sie gerne einen Beitrag leisten. Thx –

Antwort

2

Ok Ich bin auf etwas :)

Verwendung JNA Ich bin in der Lage zu rufen Sie die Win32 API (und * nix API zu) von Java.

Ich versuchte GetFileInformationByHandle Aufruf und hat zu keinem Ergebnis, aber das dwVolumeSerialNumber Attribut immer gleich 0 bekam (versucht, mit meiner C: und D: Antrieb)

Dann sah ich diese Funktion auf MSDN: MoveFileEx. Wenn der Flag-Parameter auf 0 gesetzt ist, ist die Funktion zum Kopieren bei Verschieben deaktiviert. UND ES FUNKTIONIERT !!!!

Also werde ich einfach anrufen

if (!Kernel32.INSTANCE.MoveFileEx(source.getAbsolutePath(), destination.getAbsolutePath(), 0)) { 
    System.out.println("logical move failed"); 
} 

Hier ist der Code in dem Kernel32.java Schnittstelle (diese Datei setzen in der src gefunden werden.Zip-Paket im Download-Bereich der JNA Website):

boolean MoveFileEx(String lpExistingFileName, String lpNewFileName, int dwFlags); 

int MOVEFILE_REPLACE_EXISTING = 0x01; 
int MOVEFILE_COPY_ALLOWED = 0x02; 
int MOVEFILE_CREATE_HARDLINK = 0x04; 
int MOVEFILE_WRITE_THROUGH = 0x08; 
int MOVEFILE_DELAY_UNTIL_REBOOT = 0x10; 
int MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20; 
+0

+1, MoveFileEx() ist ein guter Fund. Ich bin allerdings neugierig: Wie bekommen Sie den HANDLE-Wert, um GetFileInformationByHandle() aufzurufen? Der Eintrag dwVolumeSerialNumber wird in meinem C++ - Testprogramm sinnvoll ausgefüllt (d. H. Es ist ein Wert ungleich Null, der für verschiedene Laufwerke unterschiedlich ist). –

+0

Ich habe es mit CreateFile, die ein Datei-Handle zurückgeben. Wenn Sie CreateFile aufrufen, müssen Sie angeben, dass keine neue Datei erstellt werden muss, damit sie fehlschlägt, wenn die Datei nicht existiert. –

+0

Hmm ... CreateFile() ist der richtige Weg, um einen GRIFF zu bekommen, aber ich bin ein wenig verwirrt, warum Sie darüber gesprochen haben, dass eine neue Datei nicht erstellt werden soll - versuchen Sie möglicherweise, das Ziel zu öffnen * Datei * (die noch nicht existiert), anstelle des Zielverzeichnisses *? –

4

Auf Linux oder andere * nices, rufen stat() auf den Quell- und Zielverzeichnisse und ihre st_dev Werte vergleichen. Wenn sie identisch sind, kann eine logische Verschiebung durchgeführt werden, andernfalls muss eine physische Kopie + Löschung durchgeführt werden.

Unter Windows können Sie GetFileInformationByHandle() an Handles zu den zwei Verzeichnissen aufrufen und ihre Werte dwVolumeSerialNumber vergleichen. Beachten Sie, dass dies Windows 2000 oder höher erfordert.

Ich sehe Sie verwenden Java - (? Vielleicht JNI) es muss eine Portal sein, über die Sie dieses OS-Level-Informationen zugreifen können

+0

Wow, beeindruckend :) Ich werde versuchen, mehr Informationen darüber zu finden. Vielen Dank ! –

+0

Ich hoffe, es hilft, aber ich kann nicht garantieren, dass diese Bedingungen halten werden - es macht nur Sinn, dass sie würden;) –

+0

Oh, ich verstehe. Ich suche derzeit nach JNA (https://jna.dev.java.net/) für Kernel32 und Unix-API-Zugang. –

Verwandte Themen