سؤال

أنا أستخدم Android NDK لتقديم تطبيق في المقام الأول في C لأسباب الأداء ، ولكن يبدو أن عمليات الملفات مثل FOPEN لا تعمل بشكل صحيح في Android. كلما حاولت استخدام هذه الوظائف ، يتعطل التطبيق.

كيف يمكنني إنشاء/الكتابة إلى ملف مع Android NDK؟

هل كانت مفيدة؟

المحلول

إجابات أخرى صحيحة. يمكنك فتح ملف من خلال NDK باستخدام FILE و fopen, ولكن لا تنس وضع إذن لذلك.

في مكان Android Place:

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

نصائح أخرى

File IO يعمل بشكل جيد على Android باستخدام JNI. ربما تحاول فتح ملف بمسار سيء وعدم التحقق من رمز الإرجاع؟ لقد قمت بتعديل مثال 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!

تأكد من استخدام جافا getExternalStorageDirectory() اتصل للحصول على المسار الحقيقي إلى SDCARD لأن الأجهزة الأحدث لا تُخطط ببساطة إلى "/sdcard". في هذه الحالة ، سيفشل محاولة استخدام موقع متشددين لـ "/sdcard".

يمكنني أيضًا التحقق من أن FOPEN () يعمل بشكل صحيح ، ولكن ليس إذا كنت تحاول الوصول إلى ملف في مجلد موارد أو أصول التطبيق. أوصي ، لتجنب الاضطرار إلى إعادة اختراع العجلة ، وأن تقوم بإلصاق أي أصول تريد شحنها مع تطبيقك في مجلد الأصول ، حيث سيتم تعبئتها للتوزيع.

في حالة مجلد الأصول ، تحتاج إلى القيام بأحد أمرين ، اعتمادًا على ما إذا كان الملف مضغوطًا بواسطة Packager. كلاهما يستخدم أساليب AssetManager ، ويمكنك الحصول على AssetManager من السياق/التطبيق. تكون أسماء الملفات دائمًا بالنسبة إلى مجلد الأصول ، راجع للشغل: إذا كان لديك ملف "foo.png" مباشرة في مجلد الأصول ، فستفتح "foo.png" ، " ليس شيء مثل "الأصول/foo.png".

  1. إذا لم يكن الملف مضغوطًا (أي ، فهو أحد الامتدادات التي لا يتم ضغطها ، مثل .png) ، يمكنك الحصول على واصف ملف من AssetManager.openfd () ونقله إلى C ++. ثم يمكنك استخدام FDOPEN (DUP (FD) ، "R") ؛ لفتح الملف كملف*. لاحظ لك يجب FSEEK () إلى الإزاحة ، وتتبع طول الملف بنفسك. يمكنك حقًا الحصول على مقبض ملف إلى حزمة الأصول بأكملها ، وملف اهتمامك هو جزء صغير فقط.

  2. إذا كان ملفك مضغوطًا ، فأنت بحاجة إلى استخدام قارئ دفق Java: AssetManager.open () يمنحك inputstream يمكنك استخدام قراءة الملف فيه. هذا pita لأنه لا يمكنك الاستعلام عن حجم الملف ؛ أقوم بتشغيل خطوة معالجة مسبقة على مجلد الأصول الذي يولد قائمة بجميع الملفات بأحجامها الخاصة حتى أتمكن من معرفة ، على سبيل المثال ، كم حجم المخزن المؤقت لتخصيصه.

إذا كان ملفك موردًا ، فقد تحتاج إلى مرور فئة الموارد للوصول إليه ، على الرغم من أنه يبدو أن الموارد معبأة أيضًا في حزمة الأصول نفسها. يحتوي Resource على مكالمة OpenRawResource () للحصول على InputStream ومكالمة OpenRawResourceFD () للحصول على واصف الملف ، على النحو الوارد أعلاه ، على الرغم من.

حظا طيبا وفقك الله.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top