将jcharArray转换为具有正确编码jni的String

Convert jcharArray to String with right encoding jni

本文关键字:编码 jni String jcharArray 转换      更新时间:2023-10-16

我有返回目录中文件数组的本地方法。public static native char[][] scan(字符串路径);我不能返回字符串数组,因为如果文件编码无效-一切都崩溃了问题是正确转换char[]到java端字符串,当我尝试新的字符串(字符);我得到不可打印的字符串(无效)。请纠正我。

下面是输出的例子(If方法返回String[])

Array.toString(scan("/storage/")); -> [/storage/sdcard1,/storage/sdcard0]

if方法返回char[][];

char[][] chars = scan("/storage/");
String[] stringArray = new String[char.length];
for(int i = 0; i < chars.length; i++){
    stringArray[i] = new String(char[i]);
}
Arrays.toString(stringArray); -> //unprintable symbols [����������爀条⽥摳慣摲쉮R����,����������爀条⽥摳慣摲쉮R����]

C端发生了什么:if方法返回String[]

jobjectArray scan(JNIEnv *env, jclass cls,jstring jpath){
    std::vector<std::string> data;//contains some strings
    unsigned int size = data.size();
    jobjectArray ret = env->NewObjectArray(size,env->FindClass("java/lang/String"),NULL);
    for (unsigned int i = 0; i < size; i++){
            env->SetObjectArrayElement(ret,i,env->NewStringUTF(data.at(i).c_str()));
        }
    return ret;
}

C端:if方法返回char[][];

jobjectArray scan(JNIEnv *env, jclass cls,jstring jpath){
        std::vector<std::string> data;//contains some strings
        unsigned int size = data.size();
        jobjectArray ret = env->NewObjectArray(size, env->FindClass("[C"), NULL);
        for (unsigned int i = 0; i < size; i++){
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(toChar(env,data.at(i))));
            }
        return ret;
    }
    jcharArray toChar(JNIEnv *env, string string) {
        unsigned int n=0;
        const char* p = string.c_str();
        while(*p++){
            n++;
        } if(n<=0)
            return NULL;
        jcharArray arr = env->NewCharArray(n);
        env->SetCharArrayRegion(arr,0,n, (jchar*)p);
        return arr;
    }

您不能在非MUTF8字符串上使用NewStringUTF(其中MUTF8是由JNI规范定义的"修改的UTF-8")。

您需要在本机代码中将本地字符集转换为UTF-16,然后使用NewString,或者将byte[]的数组传递到Java代码中,然后使用接受字符集参数的String构造函数。要使用的Charset取决于您的文件系统支持什么。

现在您要么将非mutf8数据放入NewStringUTF,如果启用CheckJNI将会失败,或者您将字节值放入UTF-16字符而不进行字符集转换。