В моем случае это была проблема с владельцем каталога данных 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}'
печатает третий столбец из стандартного ввода
sudo chown -R mysql:mysql MYSQLDIR
, заменив MYSQLDIR
путем к пути к каталогу, возвращенному на шаге 1
Если вы используете 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 .
На основе библиотеки NativeCall я сделал следующее POC Application .
Оно использует функцию MoveFileA
из kernel32.dll
Поставляется как полный рабочий образец с run.bat и всеми jar и dll на месте.
Он перемещает включенный test.txt в test2.txt
Если вам не нравится версия библиотеки NativeCall. Я сделал еще одно приложение POC , основанное / возобновленное на библиотеке Java Native Access (JNA) . На этот раз реализованы и продемонстрированы MoveFileA
и MoveFileW
.
Если это действительно необходимо (renameTo не работает, и вы уверены, что MoveFile сработает), я бы использовал JNA . Похоже, что большая часть работы уже проделана в com.mucommander.file.util. Kernel32.java / Kernel32API.java .
.