programing

Android NDK에서의 파일 조작

projobs 2022. 8. 27. 23:14
반응형

Android NDK에서의 파일 조작

퍼포먼스상의 이유로 주로 C로 어플리케이션을 만들기 위해 Android NDK를 사용하고 있습니다만, Android에서는 fopen 등의 파일 조작이 정상적으로 동작하지 않는 것 같습니다.이러한 기능을 사용하려고 하면, 애플리케이션이 크래쉬 합니다.

Android NDK를 사용하여 파일을 작성/쓰기하려면 어떻게 해야 합니까?

다른 답은 정답입니다.NDK를 통해 파일을 열 수 있습니다.FILE그리고.fopen그래도 허락하는 거 잊지 마세요.

Android 매니페스트 위치:

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

파일 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)!");
}

(SD카드로) 폰으로 실행한 결과는 다음과 같습니다.

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

또, fopen()이 올바르게 동작하는 것도 확인할 수 있습니다만, 애플리케이션의 자원 또는 자산 폴더에 있는 파일에 액세스 하려고 하는 경우는 확인할 수 없습니다.번거로운 작업을 피할 수 있도록 앱과 함께 배송되는 모든 자산을 자산 폴더에 고정하고 배포용으로 패키징할 것을 권장합니다.

자산 폴더 케이스에서는 파일이 패키지 관리자에 의해 압축되었는지 여부에 따라 두 가지 작업 중 하나를 수행해야 합니다.둘 다 AssetManager 메서드를 사용하며 컨텍스트/앱에서 AssetManager를 가져올 수 있습니다.파일명은 항상 자산폴더에 상대적입니다.btw: 자산폴더에 파일 "foo.png" 가 직접 있는 경우 "assets/foo.png" 가 아닌 "foo.png" 가 열립니다.

  1. 파일이 압축되지 않은 경우(즉, .png과 같이 압축되지 않은 확장자 중 하나) AssetManager.openFd()에서 파일 설명자를 가져와 C++로 전달할 수 있습니다.그런 다음 fdopen(dup(fd)","r";을 사용하여 파일을 FILE*로 열 수 있습니다.오프셋까지 fseek()를 사용하여 파일 길이를 직접 추적해야 합니다.실제로 전체 자산 패키지에 대한 파일 처리 능력을 갖추게 됩니다. 관심 있는 파일은 극히 일부에 불과합니다.

  2. 파일이 압축된 경우 Java 스트리밍 리더를 사용해야 합니다.Asset Manager.open()은 파일을 읽을 수 있는 InputStream을 제공합니다.파일 크기를 쿼리(AFIK)할 수 없기 때문에 PITA입니다.자산 폴더에서 모든 파일의 목록을 각각의 크기로 생성하는 전처리 단계를 실행하여 할당하는 버퍼의 크기 등을 알 수 있습니다.

파일이 리소스인 경우 리소스 클래스에 액세스하려면 리소스 클래스가 필요할 수 있습니다. 그러나 리소스 클래스는 동일한 자산 패키지에 패키지되어 있습니다.리소스에는 위와 같이 InputStream을 얻기 위한 openRawResource() 호출과 파일 기술자를 얻기 위한 openRawResourceFd() 호출이 있습니다.

행운을 빌어요.

를 .getExternalStorageDirectory().sdcard는에서는 sdcard를 단순히 "/sdcard에 않기 에 sdcard에 대한 입니다.sdcard "/sdcard" 입니다.이 경우 하드코드된 "/sdcard" 위치를 사용하려고 하면 실패합니다.

이 질문에 대한 답변에 제 의견을 덧붙이고, 이 질문에 대한 답변에 명시된 올바른 권한을 설정하는 것 외에 앱에 OS의 스토리지에 액세스할 수 있는 권한을 부여하십시오.권한 메뉴는 전화기에서 전화기로 변경될 수 있습니다. 쉽게 액세스하려면 설정 메뉴로 이동한 다음 "권한"을 검색하십시오.그러면 NDK 코드에서 스토리지(sdcard 디렉터리)에 액세스할 수 있는 권한을 앱에 부여할 수 있습니다.

언급URL : https://stackoverflow.com/questions/1992953/file-operations-in-android-ndk

반응형