Pregunta

Estoy utilizando el NDK de Android para hacer una aplicación principalmente en C por razones de rendimiento, pero parece que las operaciones de archivo como fopen no funcionan correctamente en Android. Siempre que intente utilizar estas funciones, la aplicación se bloquea.

¿Cómo puedo crear / escribir en un archivo con el NDK de Android?

¿Fue útil?

Solución

Otras respuestas son correctas. Puede abrir un archivo a través de la NDK mediante FILE y fopen, pero no se olvide de colocar un permiso para ello.

En el lugar de manifiesto de Android:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

Otros consejos

Archivo IO funciona bien en Android usando JNI. Tal vez usted está intentando abrir un archivo con un mal camino y no comprobar el código de retorno? He modificado el ejemplo hello-JNI para demostrar que sí es posible abrir archivos y escribir en él. Espero que esto ayude.

/*
 * 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
 * distributed under the License is distributed 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 <string.h>
#include <jni.h>
#include <stdio.h>

/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( 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)->NewStringUTF(env, "Hello from JNI (with file io)!");
}

Este es el resultado después de correr en mi teléfono (con una tarjeta SD):

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

Asegúrese de utilizar la llamada getExternalStorageDirectory() Java para obtener la ruta real a la sdcard ya que los dispositivos más nuevos no se limitan a asignarla a "/ sdcard". En ese caso, tratando de utilizar una ubicación codificada de "/ sdcard" se producirá un error.

También puede verificar que fopen () funciona correctamente, pero no si está tratando de acceder a un archivo de recursos o activos de la aplicación de carpeta. Recomiendo, para no tener que reinventar la rueda, que se quede ningún activo que desea se entrega con la aplicación de los activos de la carpeta, donde van a ser envasadas para su distribución.

En los activos carpeta caso de tener que hacer una de dos cosas, dependiendo de si el archivo se comprime por el empaquetador. Tanto el uso de los métodos AssetManager, y se puede obtener la AssetManager del contexto / aplicación. Los nombres de archivo son siempre relativos a la carpeta de los activos, por cierto: Si dispone de un archivo "foo.png" directamente en la carpeta de los activos, que le abre "foo.png," no algo así como "activos /foo.png".

  1. Si el archivo no se ha comprimido (es decir, que es una de las extensiones que no se vuelva a comprimir, como .png), se puede obtener un descriptor de archivo de AssetManager.openFd () y pasarlo a C ++ . A continuación, puede utilizar fdopen (DUP (fd), "r"); para abrir el archivo como un archivo *. Tenga en cuenta que debe fseek () para el desplazamiento, y realizar un seguimiento de la duración del archivo de uno mismo. Usted está realmente conseguir un identificador de archivo a todo el paquete de activos, y su archivo de interés es sólo una pequeña parte.

  2. Si se comprime el archivo, es necesario utilizar el lector de streaming de Java: AssetManager.open () le da un InputStream puede utilizar la lectura de un archivo en Este es un PITA porque no se puede consulta (. Que yo sepa) el tamaño del archivo; Tengo un paso de preprocesamiento en mis activos carpeta que genera una lista de todos los archivos con sus respectivos tamaños para que pueda conocer, por ejemplo, qué tan grande de un tampón para asignar.

Si el archivo es un recurso, puede que tenga que pasar por la clase de recursos para acceder a ella, aunque parece que los recursos también se empaquetan en el mismo paquete de activos. Recurso tiene una llamada openRawResource () para obtener la una llamada openRawResourceFd () InputStream y para obtener el descriptor de archivo, como el anterior, sin embargo.

Buena suerte.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top