strerror(errno) return "Invalid argument" 当调用 read() & write() 时
strerror(errno) return "Invalid argument" when call read() & write()
我尝试通过本机方法访问 android 中的文件,但在调用读取或写入函数后我得到了 "Invalid argument"。 data_ptr 对齐到 512 字节,并在 java 中声明为字节数组。
JNIEXPORT jint JNICALL
Java_com_aa_bb_NativeRead(JNIEnv* env, jobject clazz, jbyteArray data_ptr, jint length){
int ret=0;
jsize len = (*env)->GetArrayLength(env, data_ptr);
jbyte *body = (*env)->GetByteArrayElements(env, data_ptr, 0);
fd = open(filePath, O_CREAT | O_RDWR | O_DIRECT | O_SYNC, S_IRUSR | S_IWUSR);
ret = read(fd, body, length);
if(ret<0){
LOGE("errno: %s\n", strerror(errno));
}
(*env)->ReleaseByteArrayElements(env, data_ptr, body, 0);
return ret;
}
JNIEXPORT jint JNICALL
Java_com_aa_bb_NativeWrite(JNIEnv* env, jobject clazz, jbyteArray data_ptr, jint length){
int ret=0;
jsize len = (*env)->GetArrayLength(env, data_ptr);
jbyte *body = (*env)->GetByteArrayElements(env, data_ptr, 0);
fd = open(filePath, O_CREAT | O_RDWR | O_DIRECT | O_SYNC, S_IRUSR | S_IWUSR);
ret = write(fd, body, length);
if(ret<0){
LOGE("errno: %s\n", strerror(errno));
}
(*env)->ReleaseByteArrayElements(env, data_ptr, body, 0);
return ret;
}
编辑:
如果我使用 open(filePath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
,错误就会消失。但我想使用 O_DIRECT 忽略缓存和缓冲区直接访问硬件。
O_DIRECT
要求写入是底层文件系统的倍数:
The O_DIRECT
flag may impose alignment restrictions on the length and
address of user-space buffers and the file offset of I/Os. In Linux align‐
ment restrictions vary by filesystem and kernel version and might be absent
entirely. However there is currently no filesystem-independent interface
for an application to discover these restrictions for a given file or
filesystem. Some filesystems provide their own interfaces for doing so,
for example the XFS_IOC_DIOINFO
operation in xfsctl(3)
.
Under Linux 2.4, transfer sizes, and the alignment of the user buffer and
the file offset must all be multiples of the logical block size of the
filesystem. Under Linux 2.6, alignment to 512-byte boundaries suffices.
GetByteArrayElements
不提供此类保证。它只是 returns 基本元素数组的基地址 - 在这种情况下,这是字节数组中字节的地址。这些由 Java 内存管理器分配。您要么必须复制字节(击败 O_DIRECT
的对象),删除 O_DIRECT
或使用其他一些策略来分配内存(例如使用 mmap(..., MAP_ANON)
自己分配它们) .
我尝试通过本机方法访问 android 中的文件,但在调用读取或写入函数后我得到了 "Invalid argument"。 data_ptr 对齐到 512 字节,并在 java 中声明为字节数组。
JNIEXPORT jint JNICALL
Java_com_aa_bb_NativeRead(JNIEnv* env, jobject clazz, jbyteArray data_ptr, jint length){
int ret=0;
jsize len = (*env)->GetArrayLength(env, data_ptr);
jbyte *body = (*env)->GetByteArrayElements(env, data_ptr, 0);
fd = open(filePath, O_CREAT | O_RDWR | O_DIRECT | O_SYNC, S_IRUSR | S_IWUSR);
ret = read(fd, body, length);
if(ret<0){
LOGE("errno: %s\n", strerror(errno));
}
(*env)->ReleaseByteArrayElements(env, data_ptr, body, 0);
return ret;
}
JNIEXPORT jint JNICALL
Java_com_aa_bb_NativeWrite(JNIEnv* env, jobject clazz, jbyteArray data_ptr, jint length){
int ret=0;
jsize len = (*env)->GetArrayLength(env, data_ptr);
jbyte *body = (*env)->GetByteArrayElements(env, data_ptr, 0);
fd = open(filePath, O_CREAT | O_RDWR | O_DIRECT | O_SYNC, S_IRUSR | S_IWUSR);
ret = write(fd, body, length);
if(ret<0){
LOGE("errno: %s\n", strerror(errno));
}
(*env)->ReleaseByteArrayElements(env, data_ptr, body, 0);
return ret;
}
编辑:
如果我使用 open(filePath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
,错误就会消失。但我想使用 O_DIRECT 忽略缓存和缓冲区直接访问硬件。
O_DIRECT
要求写入是底层文件系统的倍数:
The
O_DIRECT
flag may impose alignment restrictions on the length and address of user-space buffers and the file offset of I/Os. In Linux align‐ ment restrictions vary by filesystem and kernel version and might be absent entirely. However there is currently no filesystem-independent interface for an application to discover these restrictions for a given file or filesystem. Some filesystems provide their own interfaces for doing so, for example theXFS_IOC_DIOINFO
operation inxfsctl(3)
.Under Linux 2.4, transfer sizes, and the alignment of the user buffer and the file offset must all be multiples of the logical block size of the filesystem. Under Linux 2.6, alignment to 512-byte boundaries suffices.
GetByteArrayElements
不提供此类保证。它只是 returns 基本元素数组的基地址 - 在这种情况下,这是字节数组中字节的地址。这些由 Java 内存管理器分配。您要么必须复制字节(击败 O_DIRECT
的对象),删除 O_DIRECT
或使用其他一些策略来分配内存(例如使用 mmap(..., MAP_ANON)
自己分配它们) .