我尝试通过本地方法访问android中的文件,但是在调用读取或写入函数后,我得到了“无效参数”。 data_ptralignment到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忽略caching和缓冲区直接访问硬件。
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)
自己分配它们)。