Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C androidndk中的文件操作_C_File Io_Java Native Interface_Android Ndk - Fatal编程技术网

C androidndk中的文件操作

C androidndk中的文件操作,c,file-io,java-native-interface,android-ndk,C,File Io,Java Native Interface,Android Ndk,出于性能方面的考虑,我使用androidndk来制作一个主要使用C语言的应用程序,但是像fopen这样的文件操作在Android中似乎不能正常工作。每当我尝试使用这些函数时,应用程序就会崩溃 如何使用Android NDK创建/写入文件 文件IO在使用JNI的Android上运行良好。也许您试图打开一个路径不正确的文件,但没有检查返回代码?我修改了hello jni示例,以证明确实可以打开文件并对其进行写入。我希望这有帮助 /* * Copyright (C) 2009 The Android

出于性能方面的考虑,我使用androidndk来制作一个主要使用C语言的应用程序,但是像fopen这样的文件操作在Android中似乎不能正常工作。每当我尝试使用这些函数时,应用程序就会崩溃


如何使用Android NDK创建/写入文件

文件IO在使用JNI的Android上运行良好。也许您试图打开一个路径不正确的文件,但没有检查返回代码?我修改了hello jni示例,以证明确实可以打开文件并对其进行写入。我希望这有帮助

/*
 * 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)!");
}

我还可以验证fopen()是否正常工作,但如果您试图访问应用程序的resources或assets文件夹中的文件,则不能。为了避免重新发明轮子,我建议您将应用程序附带的任何资产都放在assets文件夹中,然后打包分发

在资产文件夹的情况下,您需要做两件事之一,这取决于文件是否由打包机压缩。两者都使用AssetManager方法,您可以从上下文/应用程序获取AssetManager。文件名总是相对于资产文件夹,顺便说一句:如果您的资产文件夹中直接有一个文件“foo.png”,那么您应该打开“foo.png,而不是类似于“assets/foo.png”的文件

> p>如果文件未被压缩(即,它是未被压缩的扩展之一,比如.pNG),则可以从AsStestMeals.OpenFDE()中获取文件描述符并将其传递给C++。然后可以使用fdopen(dup(fd),“r”);以文件*的形式打开文件。注意,您必须将fseek()设置为偏移量,并自己跟踪文件的长度。您实际上获得了整个资产包的文件句柄,而您感兴趣的文件只是其中的一小部分

  • 如果文件已压缩,则需要使用Java streaming reader:AssetManager.open()为您提供一个InputStream,您可以在其中使用读取文件。这是一个PITA,因为您无法查询(AFAIK)文件大小;我在我的资产文件夹上运行了一个预处理步骤,该步骤生成了一个所有文件的列表,这些文件具有各自的大小,因此我可以知道,例如,要分配多大的缓冲区

  • 如果您的文件是一个资源,您可能需要通过资源类来访问它,尽管看起来资源也打包到同一个资产包中。资源有一个openRawResource()调用来获取InputStream,还有一个openRawResourceFd()调用来获取文件描述符,如上所述


    祝你好运。

    其他答案都是正确的。您可以使用
    file
    fopen
    通过NDK打开文件,但不要忘记为其设置权限

    在Android清单位置:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
    
    
    
    确保使用Java
    getExternalStorageDirectory()
    调用获取SD卡的实际路径,因为较新的设备不会简单地将其映射到“/SD卡”。在这种情况下,尝试使用硬编码的“/sdcard”位置将失败。

    我想在这里的答案中加上我的两分钱,在设置此问题的答案中指定的正确权限的基础上,确保授予应用程序访问操作系统中存储的权限。权限菜单可以在不同的手机之间更改,一种简单的方法是进入设置菜单,然后搜索“权限”。这将使您有机会授予应用程序权限,以便从NDK代码访问存储(即SD卡目录)

    谢谢,行得通!我想我的问题是我没有使用fopen命令的完整路径。是否可以以只读模式打开驻留在资产中的文件?使用NDK打开资产更复杂,但我描述了所需的步骤。后续说明:“从AssetManager.openFd()获取文件描述符”结果证明这是一种糟糕的形式——它不是受祝福的SDK的一部分。它在当前所有手机上都能正常工作,但不能保证能继续工作。获取.APK文件的路径并不难,而是留给关心完全符合犹太标准的NDK代码的读者作为练习…留给读者作为练习?如果我不能从堆栈溢出复制粘贴代码,我该怎么做呢?…从另一个答案复制代码?或者只是自己做研究。这个答案已经有七年了。无论如何,从你自己新的经过测试的闪亮代码中构建一些东西可能是很好的,因为我写这篇文章的时候可能是在为Android 2.x开发。我只是对大学课本中的“读者练习”有一种普遍的厌恶,它似乎总是忽略了那些我最难理解的问题的答案。这是一条需要牢记的有用法则。即使是面对面,我的枯燥幽默偶尔也会被忽视,尤其是在互联网上。对不起,忘了更新这个。问题的根源是没有获得读/写权限。挂载SD卡,然后尝试打开其中的文件也可能会导致类似问题。这一点非常重要,请运行adb shell“ls/-l | grep sdcard”,以确定设备在何处映射/sdcard目录(用于调试),而不是使用
    getExternalStorageDirectory
    我使用了getenv(“外部存储”)但它不起作用。尽管在adb shell上,
    $EXTERNAL_STORAGE
    /sdcard/
    。我使用的是Android 7.1。我应该使用
    getExternalStorageDirectory
    获取路径吗?在manifest中,它起作用了!我还发现manifest文件上的更新只有在重新安装应用程序后才会生效。有时eclipse不会为您重新安装该应用程序。我在手机上删除该应用程序,然后使用eclipse重新安装。
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>