In the java 25 move, we're removing some code that uses reflection in a soon-to-be-disallowed way. Instead, we're looking at using JNA. I need to access a file descriptor (the unix kind) and I thought I'd open("some_path",O_CREAT|O_RDWR) , do whatever I need to do with the file descriptor and then open the same path with File instead.
Problem is I get errno 2 (no such file or directory).
If I create the file first with through
var f = new File("some_path");
f.createNewFile();
int fd = JNALib.open("some_path", O_CREAT|O_RDWR);
Then that works perfectly. I do not understand why the first option fails. Mac OS X, ARM Mac. JNA 5.18.1
Code:
@Test
public void testSOOpenFile() throws Exception {
String tmpFile = "dummy-file.tst";
var relPath = Paths.get("").toAbsolutePath();
Path file = Path.of(relPath + "/" + tmpFile);
System.out.println("Creating " + file);
int fd = JNALibMinimal.open(file.toString(), O_CREAT | O_RDWR);
if (fd < 0 ) {
System.out.println("JNALib failed to open with error code " + JNALib.getLastError());
} else {
System.out.println("JNALib successfully opened " + fd);
}
}
public class JNALibMinimal {
static {
Native.register(Platform.C_LIBRARY_NAME);
}
public static native int open(String pathName, int flags);
public static native int open(String pathName, int flags, int mode);
}
UPDATE I (finally) figured out the problem and it was (not uncommon) CBtK (crap behind the keyboard). I've been too long away from c programming. The problem was that linux and Darwin actually has different values for the symbols O_RDWR & O_CREAT. Once I used Darwin values, the file was created ok.
1 Answer 1
You forget the third argument: the file mode (permissions) are required when creating a file
import java.io.File;
File file = new File("some/complex/path/to/my_file.dat");
File parentDir = file.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
int fd = JNALib.INSTANCE.open(
file.getAbsolutePath(),
JNALib.O_CREAT | JNALib.O_RDWR,
JNALib.DEFAULT_MODE
);
5 Comments
open() call, file permissions are optional.
Fileis really more of a wrapper around the business of manipulating paths on the file system. Creating an object of typeFiledoesn't create anything on the file systemjava.nio.file.Files.setPosixFilePermissions()not enough for your needs?fileChannel.position(intendedSize - 1).write(ByteBuffer.allocate(1))does not work for you?