سؤال

وحين تبحث عن كيفية القيام بذلك، لقد وجدت بعض المناقشات غامضة حول خيارات مختلفة، مثل JNI مقابل JNA، ولكن ليس الكثير في الطريق من أمثلة ملموسة.

والسياق: إذا File.renameTo() جاوة لا تستطيع ان تفعل ذلك من وظيفة (لأي سبب كان، هو قليلا إشكالية )، أود أن يرتد إلى مباشرة باستخدام هذه الوظيفة الأم ويندوز، والذي يعرف في Kernel32.dll (<لأ href = "https://stackoverflow.com/questions/1000183/reliable- ملف renameto-بديل على اساس ويندوز / 1000308 # 1000308 "> من هذه الإجابة ):

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

وهكذا، باستخدام أي نهج، كيف بالضبط هل نسمي ذلك وظيفة من ضمن التعليمات البرمجية جافا؟ أنا أبحث عن أبسط طريقة، مع الحد الأدنى من غير جافا رمز أو إضافية الخطوات (على سبيل المثال في تجميع أو نشر).

هل كانت مفيدة؟

المحلول

إذا كنت أذهب مع الجيش الشعبي اليوغوسلافي، والنظر في الاحتجاج MoveFileW مباشرة - أن يحفظ الحاجة إلى توفير معلومات التكوين للاختيار بين المكالمات يونيكود وANSI

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

وتحرير: أنا قد قمت بتعديل جوابي بعد التحقق من كود - كنت مخطئا حول استخدام شار [] في التوقيع - أنه من الأفضل استخدام <لأ href = "https://jna.dev.java.net/ جافادوك / كوم / الشمس / الجيش الشعبي اليوغوسلافي / WString.html "يختلط =" noreferrer "> WString .

نصائح أخرى

إذا كان ذلك ضروريا حقا (renameTo لا يعمل وكنت على يقين سوف MoveFile)، وأود أن استخدام <لأ href = "https://github.com/twall/jna/" يختلط = "نوفولو noreferrer" > JNA . يبدو أن معظم العمل يتم بالفعل في com.mucommander.file.util. <وأ href = "http://trac.mucommander.com/browser/trunk/source/com/mucommander/file/util/Kernel32. جافا "يختلط =" نوفولو noreferrer "> Kernel32.java / <لأ href =" http://trac.mucommander.com/browser/trunk/source/com/mucommander/file/util/Kernel32API.java " يختلط = "نوفولو noreferrer"> Kernel32API.java .

واستنادا إلى مكتبة NativeCall فعلت ما يلي <لأ href = "HTTP: // www.file-upload.net/download-1706268/MoveFile.zip.html "يختلط =" نوفولو noreferrer "> POC تطبيق .

ويستخدم وظيفة MoveFileA من KERNEL32.DLL

ويتعلق الأمر عينة العمل كما كاملة مع run.bat وكل جرة ودلس في المكان.

وهي تتحرك TEST.TXT شملت لtest2.txt


إذا كنت لا تحب إصدار مكتبة NativeCall فعلت آخر POC تطبيق استنادا / resuing على جافا الوصول الأصلي (الجيش الشعبي اليوغوسلافي) المكتبة. يتم تنفيذ هذا MoveFileA الوقت وMoveFileW وأظهر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top