strerror(errno) 在调用 read() 和 write() 时返回"无效参数"



我尝试通过本机方法访问android中的文件,但是在调用读取或写入函数后得到"无效参数"。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: %sn", 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: %sn", 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要求写入是底层文件系统的倍数:

O_DIRECT标志可能会对长度和 用户空间缓冲区的地址和 I/O 的文件偏移量。 在 Linux 中对齐‐ 限制因文件系统和内核版本而异,可能不存在 完全。 但是,目前没有独立于文件系统的接口 让应用程序发现给定文件的这些限制,或者 文件系统。 一些文件系统为此提供了自己的接口, 例如xfsctl(3)中的XFS_IOC_DIOINFO操作。

在 Linux 2.4 下,传输大小、用户缓冲区和 文件偏移量必须全部是 的逻辑块大小的倍数 文件系统。 在 Linux 2.6 下,对齐 512 字节边界就足够了。

GetByteArrayElements不提供此类保证。它仅返回元素基元数组的地址 - 在本例中,这是字节数组中字节的地址。这些由 Java 内存管理器分配。您要么必须复制字节(破坏O_DIRECT的对象),删除O_DIRECT或使用其他策略来分配内存(例如自己分配mmap(..., MAP_ANON))。

相关内容

  • 没有找到相关文章

最新更新