Frage

Während der Suche nach, wie Sie dies tun, fand ich einige vage Diskussion über die verschiedenen Optionen, wie JNI vs JNA, aber nicht viel in der Art von konkreten Beispielen.

Kontext:wenn Java File.renameTo() kann es nicht tun, ist Arbeit (für was auch immer Grund; es ist ein wenig problematisch), Würde ich gerne zurückgreifen, um direkt über das native Windows-Funktion, die definiert ist, in kernel32.dll (aus dieser Antwort):

BOOL WINAPI MoveFile(
  __in  LPCTSTR lpExistingFileName,
  __in  LPCTSTR lpNewFileName
);

So, mit was auch immer Ansatz, wie genau würden Sie diese Funktion aus Java-code?Ich bin auf der Suche nach dem einfachsten Weg, mit dem minimum an nicht-Java-code oder extra Schritte (wie z.B.in der Zusammenstellung und Bereitstellung).

War es hilfreich?

Lösung

Wenn Sie gehen mit JNA, berücksichtigen aufrufen MoveFileW direkt - es spart zu bieten, Konfiguration info zur Wahl zwischen Unicode-und ANSI-Anrufe.

import java.io.*;
import com.sun.jna.*;

public class Ren {

  static interface Kernel32 extends Library {
    public static Kernel32 INSTANCE = (Kernel32) Native
        .loadLibrary("Kernel32", Kernel32.class);

    public static int FORMAT_MESSAGE_FROM_SYSTEM = 4096;
    public static int FORMAT_MESSAGE_IGNORE_INSERTS = 512;

    public boolean MoveFileW(WString lpExistingFileName,
        WString lpNewFileName);

    public int GetLastError();

    public int FormatMessageW(int dwFlags,
        Pointer lpSource, int dwMessageId,
        int dwLanguageId, char[] lpBuffer, int nSize,
        Pointer Arguments);
  }

  public static String getLastError() {
    int dwMessageId = Kernel32.INSTANCE.GetLastError();
    char[] lpBuffer = new char[1024];
    int lenW = Kernel32.INSTANCE.FormatMessageW(
        Kernel32.FORMAT_MESSAGE_FROM_SYSTEM
            | Kernel32.FORMAT_MESSAGE_IGNORE_INSERTS, null,
        dwMessageId, 0, lpBuffer, lpBuffer.length, null);
    return new String(lpBuffer, 0, lenW);
  }

  public static void main(String[] args) throws IOException {
    String from = ".\\from.txt";
    String to = ".\\to.txt";
    new FileOutputStream(from).close();
    if (!Kernel32.INSTANCE.MoveFileW(new WString(from),
        new WString(to))) {
      throw new IOException(getLastError());
    }
  }
}

EDIT:Ich habe bearbeitet Sie meine Antwort nach überprüfung der code - ich irrte über die Verwendung von char[] in der Signatur ist es besser zu verwenden WString.

Andere Tipps

Wenn dies wirklich notwendig ist (renameTo funktioniert nicht und du bist sicher, MoveFile wird), würde ich verwenden JNA.Es sieht aus wie der Großteil der Arbeit ist bereits getan com.mucommander.Datei.util.Kernel32.java/Kernel32API.java.

Auf der Grundlage der NativeCall Bibliothek Ich habe die folgenden POC-Anwendung.

Es nutzt die MoveFileA Funktion kernel32.dll

Es kommt als komplettes Beispiel arbeiten mit einem run.Fledermaus und alle jar und dlls im Ort.

Es verschiebt die enthalten test.txt zu test2.txt


Wenn Sie nicht wie die NativeCall library version ich habe eine andere POC-Anwendung basierend auf/resuing auf die Java Native Access - (JNA) Bibliothek.Dieses mal MoveFileA und MoveFileW umgesetzt und demonstriert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top