У меня есть собственный метод, который возвращает массив файлов в каталоге. public static native char [] [] scan (String path); Я не могу вернуть массив строк, потому что, если файл имеет недопустимый encoding-, все сбои. Проблема заключается в правильном преобразовании char [] в String на стороне java, когда я пытаюсь использовать новую строку String (chars); Я получаю непечатаемую строку (недействительно). Пожалуйста, поправьте меня.
Вот пример вывода (если метод возвращает String [])
Array.toString(scan("/storage/"));
→ [/storage/sdcard1,/storage/sdcard0]
Вот если метод возвращает 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: если метод возвращает 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: если метод возвращает 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;
}
Вы не можете использовать NewStringUTF
для строк, отличных от MUTF8 (где MUTF8 - это "модифицированный UTF-8", определенный спецификацией JNI).
Вам нужно либо преобразовать локальный набор символов в UTF-16 в собственный код, а затем использовать NewString
или передать массивы byte[]
в ваш код Java, а затем использовать конструктор String, который принимает аргумент charset. Используемая кодировка зависит от того, что поддерживает ваша файловая система.
Прямо сейчас вы либо помещаете данные без MUTF8 в NewStringUTF
, которые будут шумно звучать, если CheckJNI включен, или вы помещаете байтовые значения в символы UTF-16 без преобразования кодировки.