Opérations sur les fichiers dans Android NDK

J’utilise le NDK Android pour créer une application principalement en C pour des raisons de performances, mais il semble que les opérations sur les fichiers telles que fopen ne fonctionnent pas correctement sous Android. Chaque fois que j’essaie d’utiliser ces fonctions, l’application se bloque.

Comment créer / écrire dans un fichier avec le NDK Android?

Tout ce qui précède est correct. Vous pouvez ouvrir un fichier via le NDK en utilisant FILE et fopen. MAIS … N’oubliez pas de lui accorder une permission. dans le manifeste Android un

 

Fichier IO fonctionne très bien sur Android en utilisant JNI. Vous essayez peut-être d’ouvrir un fichier avec un chemin incorrect et de ne pas vérifier le code retour? J’ai modifié l’exemple hello-jni pour démontrer qu’il est effectivement possible d’ouvrir un fichier et d’y écrire. J’espère que ça aide.

 /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * dissortingbuted under the License is dissortingbuted on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include  #include  #include  /* This is a sortingvial JNI example where we use a native method * to return a new VM Ssortingng. See the corresponding Java source * file located at: * * apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java */ jssortingng Java_com_example_hellojni_HelloJni_ssortingngFromJNI( JNIEnv* env, jobject thiz ) { FILE* file = fopen("/sdcard/hello.txt","w+"); if (file != NULL) { fputs("HELLO WORLD!\n", file); fflush(file); fclose(file); } return (*env)->NewSsortingngUTF(env, "Hello from JNI (with file io)!"); } 

Voici le résultat après l’avoir exécuté sur mon téléphone (avec une carte SD):

 $ adb -d shell cat /sdcard/hello.txt HELLO WORLD! 

Je peux également vérifier que fopen () fonctionne correctement, mais pas si vous essayez d’accéder à un fichier dans le dossier de ressources ou d’actifs de l’application. Je recommande, pour ne pas avoir à réinventer la roue, de coller tous les éléments que vous souhaitez envoyer avec votre application dans le dossier des ressources, où ils seront empaquetés pour la dissortingbution.

Dans le dossier du dossier des ressources, vous devez effectuer l’une des deux opérations suivantes, selon que le fichier a été compressé par le conditionneur. Les deux utilisent les méthodes AssetManager et vous pouvez obtenir AssetManager à partir du contexte / de l’application. Les noms de fichiers sont toujours relatifs au dossier assets, btw: Si vous avez un fichier “foo.png” directement dans le dossier assets, vous ouvrez “foo.png”, pas quelque chose comme “assets / foo.png”.

  1. Si le fichier n’a pas été compressé (c’est-à-dire qu’il s’agit d’une des extensions non compressées, comme .png), vous pouvez obtenir un descripteur de fichier à partir de AssetManager.openFd () et le transmettre à C ++. Vous pouvez alors utiliser fdopen (dup (fd), “r”); pour ouvrir le fichier en tant que FICHIER *. Notez que vous devez effectuer une recherche () sur le décalage et suivre vous-même la longueur du fichier. En réalité, vous obtenez un descripteur de fichier pour l’ensemble du package de ressources, et votre fichier ne représente qu’une petite partie.

  2. Si votre fichier est compressé, vous devez utiliser le lecteur de streaming Java: AssetManager.open () vous donne un InputStream dans lequel vous pouvez lire le fichier. Il s’agit d’un fichier PITA car vous ne pouvez pas interroger (AFAIK) la taille du fichier; Je lance une étape de prétraitement sur mon dossier de ressources, qui génère une liste de tous les fichiers avec leurs tailles respectives, afin que je puisse savoir, par exemple, la taille du tampon à allouer.

Si votre fichier est une ressource, vous devrez peut-être passer par la classe Resource pour y accéder, même s’il semble que les ressources soient également regroupées dans le même package de ressources. Une ressource a un appel openRawResource () pour obtenir l’appel InputStream et un appel openRawResourceFd () pour obtenir le descripteur de fichier, comme ci-dessus.

Bonne chance.

Veillez à utiliser l’appel Java getExternalStorageDirectory() pour obtenir le chemin réel vers la carte SD, car les nouveaux périphériques ne le getExternalStorageDirectory() pas simplement sur “/ sdcard”. Dans ce cas, essayer d’utiliser un emplacement codé en dur de “/ sdcard” échouera.