2010-01-02 17 views
57

में फ़ाइल ऑपरेशंस मैं मुख्य रूप से प्रदर्शन कारणों से सी में एप्लिकेशन बनाने के लिए एंड्रॉइड एनडीके का उपयोग कर रहा हूं, लेकिन ऐसा लगता है कि फ़ॉपेन जैसे फ़ाइल ऑपरेशन एंड्रॉइड में सही तरीके से काम नहीं करते हैं। जब भी मैं इन कार्यों का उपयोग करने की कोशिश करता हूं, तो एप्लिकेशन क्रैश हो जाता है।एंड्रॉइड एनडीके

मैं Android NDK के साथ फ़ाइल को कैसे बना/लिखूं?

+1

क्षमा करें इसे अपडेट करना भूल गया। समस्या की जड़ को पढ़ने/लिखने की अनुमति नहीं मिल रही थी। एसडीकार्ड घुड़सवार होने और फिर इसमें एक फ़ाइल खोलने की कोशिश कर एक समान समस्या भी हो सकती है। – RyanCheu

+0

मैं आपके साथ एक ही समस्या आती हूं, क्या आपने इसे हल किया है? –

उत्तर

51

उपर्युक्त सभी सही है। आप FILE और fopen का उपयोग करके एनडीके के माध्यम से एक फ़ाइल खोल सकते हैं। लेकिन ... इसके लिए अनुमति देने के लिए मत भूलना। एंड्रॉयड में जगह प्रकट एक

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

इस लाइन को मेनिफेस्ट फ़ाइल में कहां रखा जाएगा? – Dhasneem

+0

मेनिफेस्ट में http://developer.android.com/guide/topics/manifest/uses-permission-element.html –

+0

धन्यवाद, यह काम करता है! और मैंने यह भी पाया कि मैनिफेस्ट फ़ाइल पर अपडेट केवल ऐप को दोबारा इंस्टॉल करने के बाद ही प्रभावी होंगे। कभी-कभी ग्रहण आपके लिए ऐप को दोबारा इंस्टॉल नहीं करेगा। मैं अपने फोन पर ऐप हटा देता हूं और ग्रहण का उपयोग करके इसे पुनः इंस्टॉल करता हूं। –

57

फ़ाइल आईओ जेएनआई का उपयोग कर एंड्रॉइड पर ठीक काम करता है। शायद आप एक खराब पथ के साथ फाइल खोलने की कोशिश कर रहे हैं और रिटर्न कोड की जांच नहीं कर रहे हैं? मैंने हैलो-जेनी उदाहरण को संशोधित करने के लिए संशोधित किया कि फ़ाइल खोलना और इसे लिखना वास्तव में संभव है। आशा है कि ये आपकी मदद करेगा।

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

यहाँ अपने फोन पर यह चल रहा है (एक एसडी कार्ड के साथ) के बाद परिणाम है:

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

धन्यवाद, यह काम करता है! मुझे लगता है कि मेरी समस्या यह थी कि मैं अपने fopen कमांड के लिए एक पूर्ण पथ का उपयोग नहीं कर रहा था। – RyanCheu

+2

क्या एक फ़ाइल को खोलना संभव होगा जो संपत्तियों में केवल पढ़ने के मोड में रहता है? – dzhelil

+1

एनडीके का उपयोग कर संपत्ति खोलना अधिक जटिल है लेकिन मैं आवश्यक चरणों का वर्णन करता हूं [यहां] (http://stackoverflow.com/questions/2651816/reading-resource-files-from-my-own-apk-in-android-native -environment/2663962 # 2663962)। –

18

मैं भी (कि fopen सत्यापित कर सकते हैं) सही ढंग से काम करता है, लेकिन नहीं अगर आप एप्लिकेशन के संसाधनों या संपत्ति फ़ोल्डर में फ़ाइल तक पहुंचने का प्रयास कर रहा है। मैं सलाह देता हूं कि पहिया को फिर से शुरू करने से बचने के लिए, आप संपत्तियों फ़ोल्डर में अपने ऐप के साथ भेजे गए किसी भी संपत्ति को चिपकाते हैं, जहां उन्हें वितरण के लिए पैक किया जाएगा।

संपत्ति फ़ोल्डर मामले में आपको दो चीज़ों में से एक करने की आवश्यकता है, इस पर निर्भर करता है कि फ़ाइल पैकेजर द्वारा संपीड़ित की गई थी या नहीं। दोनों AssetManager विधियों का उपयोग करते हैं, और आप संदर्भ/ऐप से AssetManager प्राप्त कर सकते हैं। फ़ाइल नाम हमेशा संपत्ति फ़ोल्डर से संबंधित होते हैं, btw: अगर आपके पास संपत्ति फ़ोल्डर में सीधे "foo.png" फ़ाइल है, तो आप "foo.png," नहीं "संपत्ति/foo.png" जैसे कुछ खोलेंगे। ।

  1. फ़ाइल संकुचित नहीं किया गया था (यानी, यह एक्सटेंशन कि संकुचित नहीं मिलता है, .png तरह से एक है), तो आप AssetManager.openFd (से एक फ़ाइल वर्णनकर्ता) मिलता है और करने के लिए इसे पारित कर सकते हैं सी ++। फिर आप fdopen (डुप्लिकेट (एफडी), "आर") का उपयोग कर सकते हैं; फाइल को फ़ाइल के रूप में खोलने के लिए *। ध्यान दें कि ऑफसेट में fseek() होना चाहिए, और फ़ाइल की लंबाई का ट्रैक रखें। आपको वास्तव में संपूर्ण संपत्ति पैकेज में फ़ाइल हैंडल मिल रहा है, और आपकी रुचि की फ़ाइल केवल एक छोटा सा हिस्सा है।

  2. यदि आपकी फ़ाइल संपीड़ित है, तो आपको जावा स्ट्रीमिंग रीडर का उपयोग करने की आवश्यकता है: AssetManager.open() आपको एक इनपुटस्ट्रीम देता है, आप फ़ाइल को पढ़ने में उपयोग कर सकते हैं। यह एक पिटा है क्योंकि आप क्वेरी नहीं कर सकते (AFAIK) फ़ाइल का आकार; मैं अपने परिसंपत्ति फ़ोल्डर पर एक प्रीप्रोकैसिंग चरण चलाता हूं जो सभी फाइलों की सूची को उनके संबंधित आकारों से उत्पन्न करता है, इसलिए मैं जान सकता हूं, उदाहरण के लिए, बफर का कितना बड़ा आवंटन करना है।

आपकी फ़ाइल एक संसाधन है, तो आप इसे उपयोग करने के लिए संसाधन वर्ग के माध्यम से जाना, ऐसा लगता है, हालांकि संसाधन भी एक ही संपत्ति पैकेज में पैक किया जाता है की आवश्यकता हो सकती। संसाधन के पास ओपनआरओ रिसोर्स() कॉल है जो इनपुटस्ट्रीम और ओपनआरओआरसोर्सएफडी() कॉल को फ़ाइल डिस्क्रिप्टर प्राप्त करने के लिए कॉल करता है, जैसा ऊपर है।

शुभकामनाएं।

+0

फॉलो-अप नोट: "AssetManager.openFd() से फ़ाइल डिस्क्रिप्टर प्राप्त करें" खराब फॉर्म साबित होता है - यह धन्य एसडीके का हिस्सा नहीं है। यह सभी मौजूदा फोन पर काम करने के लिए होता है, लेकिन यह काम जारी रखने की गारंटी नहीं है। .एपीके फ़ाइल का मार्ग प्राप्त करना कठिन नहीं होता है, और पाठक को एक अभ्यास के रूप में छोड़ दिया जाता है जो पूरी तरह से कोशेर एनडीके कोड की परवाह करता है। – SomeCallMeTim

18

जावा getExternalStorageDirectory() कॉल उपयोग करने के लिए sdcard के लिए वास्तविक पथ प्राप्त करने के लिए सुनिश्चित करें के बाद से अधिक नए डिवाइस उसे केवल "/ sdcard" करने के लिए नक्शे नहीं है।उस स्थिति में "/ sdcard" के हार्डकोड किए गए स्थान का उपयोग करने का प्रयास विफल हो जाएगा।

+3

यह वास्तव में बहुत महत्वपूर्ण है – KaiserJohaan

संबंधित मुद्दे