While searching for how to do this, I found some vague discussion about different options, like JNI vs JNA, but not much in the way of concrete examples.
Context: if Java's File.renameTo()
cannot do it's job (for whatever reason; it is a little problematic), I'd like to fall back to directly using this native Windows function, which is defined in kernel32.dll (from this answer):
BOOL WINAPI MoveFile(
__in LPCTSTR lpExistingFileName,
__in LPCTSTR lpNewFileName
);
So, using whatever approach, how exactly would you call that function from within Java code? I'm looking for the simplest way, with the minimum amount of non-Java code or extra steps (e.g. in compilation or deployment).
It basically acts as an interface between user applications and hardware. The major aim of kernel is to manage communication between software i.e. user-level applications and hardware i.e., CPU and disk memory. To establish communication between user level application and hardware. To decide state of incoming processes. To control disk management.
Application programs run separately from the kernel in the operating system and merely draw on its functions. Without the kernel, communication between programs and hardware wouldn’t be possible.
Kernel acts as a bridge between applications and data processing performed at hardware level using inter-process communication and system calls. Kernel loads first into memory when an operating system is loaded and remains into memory until operating system is shut down again.
A process can access I/O Hardware registers to program it, can execute OS kernel code and access kernel data in Kernel mode. Anything related to Process management, IO hardware management, and Memory management requires process to execute in Kernel mode.
If you go with JNA, consider invoking MoveFileW directly - it saves having to provide configuration info to choose between Unicode and ANSI calls.
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: I've edited my answer after checking the code - I was mistaken about using char[] in the signature - it is better to use WString.
If this is really necessary (renameTo doesn't work and you're sure MoveFile will), I would use JNA. It looks like most of the work is already done in com.mucommander.file.util.Kernel32.java/Kernel32API.java.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With