Что самый легкий путь состоит в том, чтобы вызвать функцию ядра Windows от Java?

В моем случае это была проблема с владельцем каталога данных MySQL, как предлагали другие. Однако установка на моем сервере была довольно необычной, используя разные каталоги, поэтому вот более подробное решение:

  1. Найти каталог данных MySQL

grep 'datadir' $(find /etc -iname my.cnf 2>/dev/null) | awk '{print $3}'

Если конфигурация MySQL находится в правильном месте, она возвращает, например, /var/lib/mysql

Если результат не возвращается, попробуйте выполнить поиск по всей файловой системе, используя

grep 'datadir' $(find / -iname my.cnf 2>/dev/null) | awk '{print $3}' (это может занять много времени)

Break down:

find /etc -iname my.cnf 2>/dev/null находит файл с именем my.cnf в /etc, игнорируя ошибки

grep 'datadir' /etc/mysql/my.cnf находит datadir в файле, найденном на предыдущем шаге

awk '{print $3}' печатает третий столбец из стандартного ввода

  1. Исправьте владение

sudo chown -R mysql:mysql MYSQLDIR, заменив MYSQLDIR путем к пути к каталогу, возвращенному на шаге 1

7
задан Community 23 May 2017 в 11:50
поделиться

3 ответа

Если вы используете JNA, подумайте о прямом вызове MoveFileW - это избавляет от необходимости предоставлять информацию о конфигурации для выбора между вызовами Unicode и 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());
    }
  }
}

EDIT: Я отредактировал свой ответ после проверки кода - ошибся с использованием char [] в подписи - лучше использовать WString .

7
ответ дан 7 December 2019 в 03:20
поделиться

На основе библиотеки NativeCall я сделал следующее POC Application .

Оно использует функцию MoveFileA из kernel32.dll

Поставляется как полный рабочий образец с run.bat и всеми jar и dll на месте.

Он перемещает включенный test.txt в test2.txt


Если вам не нравится версия библиотеки NativeCall. Я сделал еще одно приложение POC , основанное / возобновленное на библиотеке Java Native Access (JNA) . На этот раз реализованы и продемонстрированы MoveFileA и MoveFileW .

1
ответ дан 7 December 2019 в 03:20
поделиться

Если это действительно необходимо (renameTo не работает, и вы уверены, что MoveFile сработает), я бы использовал JNA . Похоже, что большая часть работы уже проделана в com.mucommander.file.util. Kernel32.java / Kernel32API.java .

.
1
ответ дан 7 December 2019 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: