संपत्ति से फाइल पढ़ें


178
public class Utils {
    public static List<Message> getMessages() {
        //File file = new File("file:///android_asset/helloworld.txt");
        AssetManager assetManager = getAssets();
        InputStream ims = assetManager.open("helloworld.txt");    
     }
}

मैं इस कोड का उपयोग संपत्ति से एक फ़ाइल को पढ़ने की कोशिश कर रहा हूं। मैंने ऐसा करने के दो तरीके आजमाए। सबसे पहले, जब Fileमैं प्रयोग किया जाता है FileNotFoundException, जब AssetManager getAssets()विधि का उपयोग कर मान्यता प्राप्त नहीं है। क्या यहां कोई समाधान है?

जवाबों:


225

यहाँ मैं बफ़र्ड पढ़ने के लिए एक गतिविधि में क्या कर रहा हूँ, अपनी आवश्यकताओं का मिलान करने के लिए विस्तार / संशोधन करें

BufferedReader reader = null;
try {
    reader = new BufferedReader(
        new InputStreamReader(getAssets().open("filename.txt")));

    // do reading, usually loop until end of file reading  
    String mLine;
    while ((mLine = reader.readLine()) != null) {
       //process line
       ...
    }
} catch (IOException e) {
    //log the exception
} finally {
    if (reader != null) {
         try {
             reader.close();
         } catch (IOException e) {
             //log the exception
         }
    }
}

संपादित करें: यदि आपका प्रश्न किसी गतिविधि के बाहर करने का तरीका है, तो मेरा उत्तर शायद बेकार है। यदि आपका सवाल बस एसेट से फाइल पढ़ने का है तो उत्तर ऊपर है।

अद्यतन :

टाइप निर्दिष्ट करने वाली फ़ाइल खोलने के लिए केवल इनपुटस्ट्रीमरएडर कॉल में टाइप करें।

BufferedReader reader = null;
try {
    reader = new BufferedReader(
        new InputStreamReader(getAssets().open("filename.txt"), "UTF-8")); 

    // do reading, usually loop until end of file reading 
    String mLine;
    while ((mLine = reader.readLine()) != null) {
       //process line
       ...
    }
} catch (IOException e) {
    //log the exception
} finally {
    if (reader != null) {
         try {
             reader.close();
         } catch (IOException e) {
             //log the exception
         }
    }
}

संपादित करें

जैसा कि @Stan टिप्पणी में कहता है, जो कोड मैं दे रहा हूं वह लाइनों को समेटने वाला नहीं है। mLineहर पास को बदल दिया जाता है। इसलिए मैंने लिखा है //process line। मुझे लगता है कि फ़ाइल में किसी प्रकार का डेटा (यानी एक संपर्क सूची) है और प्रत्येक पंक्ति को अलग से संसाधित किया जाना चाहिए।

यदि आप किसी भी तरह की प्रोसेसिंग के बिना फाइल लोड करना चाहते हैं, तो आपको mLineप्रत्येक पास का उपयोग करके StringBuilder()और पास करके प्रत्येक पास में योग करना होगा।

पुराने संस्करण

@Vincent की टिप्पणी के अनुसार मैंने finallyब्लॉक को जोड़ा ।

यह भी ध्यान रखें कि जावा 7 में और ऊपरी आप उपयोग कर सकते हैं try-with-resourcesका उपयोग करने के AutoCloseableलिए और Closeableहाल ही में जावा के सुविधाएँ।

संदर्भ

कि बाहर एक टिप्पणी @LunarWatcher अंक में getAssets()एक है classमें context। इसलिए, यदि आप इसे कॉल करते हैं, तो आपको इसे activityसंदर्भित करने और गतिविधि के संदर्भ संदर्भ को पास करने की आवश्यकता है।

ContextInstance.getAssets();

यह @Maneesh के उत्तर में बताया गया है। तो अगर यह आपके लिए उपयोगी है, तो उसके उत्तर को रोकें क्योंकि वह उसे इंगित करता है।


2
@Stan, तो टिप्पणियों में इसके बारे में लिखें और लेखक को यह तय करने दें कि क्या वे इसे अपडेट करना चाहते हैं। संपादन स्पष्टता में सुधार के लिए हैं, न कि अर्थ बदलने के लिए। कोड संशोधन हमेशा टिप्पणी के रूप में पोस्ट किए जाने चाहिए।
काइलमीट

2
आपका कोड स्ट्रीम को बंद करने और संसाधन को समय पर मुक्त करने की गारंटी नहीं देता है। मैं आपको उपयोग करने की सलाह देता हूं finally {reader.close();}
विंसेंट कैंटिन

2
मुझे लगता है कि यह इंगित करना उपयोगी है कि ऊपर दिया गया कोड ADT में एक त्रुटि दिखाता है - "Reader.close ();" लाइन को दूसरे ट्राइ-कैच ब्लॉक में डालने की आवश्यकता है। इस धागे की जाँच करें: stackoverflow.com/questions/8981589/… :)
JakeP

1
getAssets Context में एक वर्ग है, इसलिए बाहर की गतिविधि के उपयोग के लिए Context पर कॉल करने की आवश्यकता होती है। एक गतिविधि के बाहर, यह कुछ इस तरह होगाcontext.getAssets(.....)
ज़ो

1
आपके अपडेट के अनुसार (उस btw को जोड़ने के लिए धन्यवाद), स्थैतिक क्षेत्रों में संदर्भ होना स्मृति रिसाव है। यह सावधानी के साथ इस्तेमाल किया जाना चाहिए और ठीक से साफ किया जाना चाहिए। अन्यथा आप एक स्मृति रिसाव के साथ समाप्त होते हैं जो ऐप पर बहुत प्रभाव डाल सकता है।
जो

65
getAssets()

केवल अन्य किसी भी वर्ग में गतिविधि में काम करता है जिसे आपको इसके लिए उपयोग Contextकरना है।

यूटिल्स क्लास पास गतिविधि (बदसूरत तरीका) के संदर्भ के लिए एक निर्माता बनाएं या इसके लिए एक पैरामीटर के रूप में आवेदन का संदर्भ दें। उस उपयोग का उपयोग करके अपने यूटिल्स वर्ग में गेटएसेट () प्राप्त करें।


1
यह ऐसी किसी भी चीज़ पर काम करता है जो प्रसंग का उपवर्ग है, जिसमें से गतिविधि कई में से एक है।
जेरेमी लोगान

बस मैंने लिखा है Context
user370305

@ user370305 क्या आप जानते हैं, मैं InputStream को FileInputStream में कैसे बदल सकता हूँ?
हॉटहेड

@ user370305 किस तरह से यह बदसूरत है?
सेवस्तन सवण्युक

परिणाम पर विचार किए बिना यूआई वस्तुओं को पास करना आमतौर पर एक बुरा अभ्यास है। यदि आप सावधान नहीं हैं, तो आप मेमोरी लीक या मृत संदर्भों का उपयोग करने का प्रयास कर सकते हैं। विषय पर अच्छा पढ़ें: android.jlelse.eu/memory-leak-patterns-in-android-4741a7fcb570
milosmns

49

देर आए दुरुस्त आए।

मुझे कुछ परिस्थितियों में फ़ाइलों को लाइन द्वारा पढ़ने में कठिनाई हुई। नीचे दी गई विधि मुझे अब तक मिली सबसे अच्छी है, और मैं इसकी सलाह देता हूं।

उपयोग: String yourData = LoadData("YourDataFile.txt");

जहां YourDataFile.txt को संपत्ति में निवास करने के लिए माना जाता है /

 public String LoadData(String inFile) {
        String tContents = "";

    try {
        InputStream stream = getAssets().open(inFile);

        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        tContents = new String(buffer);
    } catch (IOException e) {
        // Handle exceptions here
    }

    return tContents;

 }

मेरा रिटर्न स्ट्रिंग android.content.res.ssetManager>
AssetInputStream@4195dfa0 है

यहाँ वही, Res.AssetManager $ AssetInputStream @ .... कोई विशेष कारण है कि वह इसे क्यों लौटा रहा है?
बिग्स

आप मेमोरी को डबल-आबंटित करते हैं - पहले बफर के लिए और फिर स्ट्रिंग के लिए। बड़ी फ़ाइलों के लिए काम नहीं करता है।
जाकल २L ’

1
बफर को आकार आवंटित करने का सही तरीका stream.available()
कासिम रंगवाला

39
public String ReadFromfile(String fileName, Context context) {
    StringBuilder returnString = new StringBuilder();
    InputStream fIn = null;
    InputStreamReader isr = null;
    BufferedReader input = null;
    try {
        fIn = context.getResources().getAssets()
                .open(fileName, Context.MODE_WORLD_READABLE);
        isr = new InputStreamReader(fIn);
        input = new BufferedReader(isr);
        String line = "";
        while ((line = input.readLine()) != null) {
            returnString.append(line);
        }
    } catch (Exception e) {
        e.getMessage();
    } finally {
        try {
            if (isr != null)
                isr.close();
            if (fIn != null)
                fIn.close();
            if (input != null)
                input.close();
        } catch (Exception e2) {
            e2.getMessage();
        }
    }
    return returnString.toString();
}

आप सोचते होंगे कि यदि आप बफ़रड्रेडर को बंद कर देते हैं, तो इससे स्वचालित रूप से InputStreanReader और InputStream को भी बंद करना होगा। क्योंकि यह क्या आप उन लोगों के लिए एक हैंडल नहीं बनाते हैं, जैसे input = new BufferedReader(new InputStreamReader(fIn));
ट्रांस

3
मैं अंत में आपके सभी संसाधनों को बंद करने के लिए अलग-अलग कोशिश / कैच ब्लॉक बनाने का सुझाव दूंगा; बजाय उन सभी को एक में लादने के - जैसे कि यह अन्य संसाधनों को छोड़ सकता है यदि किसी अन्य संसाधन को बंद करने का पूर्व प्रयास अपवाद को फेंकता है।
Reece

9
AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
    inputStream = assetManager.open("helloworld.txt");
}
catch (IOException e){
    Log.e("message: ",e.getMessage());
}

8

कोटलिन के लिए एक लाइन समाधान:

fun readFileText(fileName: String): String {
    return assets.open(fileName).bufferedReader().use { it.readText() }
}

7

getAssets() जब आप एक्टिविटी क्लास के अंदर कॉल कर रहे हैं तो यह विधि काम करेगी।

यदि आप इस विधि को गैर-गतिविधि वर्ग में बुला रहे हैं, तो आपको इस विधि को Context से कॉल करने की आवश्यकता है जो गतिविधि वर्ग से पास की गई है। तो नीचे विधि द्वारा आप इस विधि का उपयोग कर सकते हैं।

ContextInstance.getAssets();

ContextInstance इसे गतिविधि वर्ग के रूप में पारित किया जा सकता है।


5

फ़ाइलों को पढ़ना और लिखना हमेशा क्रियात्मक और त्रुटि-प्रवण रहा है। इन उत्तरों से बचें और इसके स्थान पर केवल Okio का उपयोग करें :

public void readLines(File file) throws IOException {
  try (BufferedSource source = Okio.buffer(Okio.source(file))) {
    for (String line; (line = source.readUtf8Line()) != null; ) {
      if (line.contains("square")) {
        System.out.println(line);
      }
    }
  }
}

1
क्या आप जानते हैं कि यह अधिक सौंदर्यवादी और छोटा क्यों दिखता है? ठीक है, क्योंकि आपने छोड़ दिया है, कम से कम, यहां कोड का आधा हिस्सा। छोड़े गए भाग: 1) IOExceptionकी कोशिश / पकड़ 2 ब्लॉक) मामले अपवाद में धाराएँ बंद करना फेंक दिया जाता है 3) यह कोड एक एकल पंक्ति को पढ़ता है, न कि पूरी फ़ाइल को। प्रदर्शन-वार, यह पुस्तकालय निश्चित रूप से अपनी तरह का है, इस पर कोई संदेह नहीं है। अब, मुझे बताएं कि क्या मुझे अभी भी "इन उत्तरों" से बचना चाहिए और ओको को केवल फाइलों को पढ़ने के लिए लागू करना चाहिए? जवाब नहीं है, जब तक कि यह आपके ऐप का हिस्सा न हो।
फरीद

मेरे उत्तर को अपडेट किया।
साकेत

4

संपत्ति में फ़ाइल पढ़ने की एक विधि इस प्रकार है:

/**
 * Reads the text of an asset. Should not be run on the UI thread.
 * 
 * @param mgr
 *            The {@link AssetManager} obtained via {@link Context#getAssets()}
 * @param path
 *            The path to the asset.
 * @return The plain text of the asset
 */
public static String readAsset(AssetManager mgr, String path) {
    String contents = "";
    InputStream is = null;
    BufferedReader reader = null;
    try {
        is = mgr.open(path);
        reader = new BufferedReader(new InputStreamReader(is));
        contents = reader.readLine();
        String line = null;
        while ((line = reader.readLine()) != null) {
            contents += '\n' + line;
        }
    } catch (final Exception e) {
        e.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException ignored) {
            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ignored) {
            }
        }
    }
    return contents;
}

यह एक अच्छा जवाब है, लेकिन यह स्ट्रिंग कॉन्सेप्टन का उपयोग करने के लिए बुरा दृष्टिकोण है। इसके बजाय StringBuilder का उपयोग करने पर विचार करें। StringBuilder सामग्रीBuilder = नया StringBuilder (); जबकि ((लाइन = Reader.readLine ())! = null) {buildder.append ("\ n")। परिशिष्ट (लाइन); } और अंत में आप इसके द्वारा नई स्ट्रिंग ऑब्जेक्ट बना सकते हैं: सामग्री = contentBuilder.toString ();
Barterio

4

आप फ़ाइल से सामग्री लोड कर सकते हैं। विचार करें कि फ़ाइल संपत्ति फ़ोल्डर में मौजूद है।

public static InputStream loadInputStreamFromAssetFile(Context context, String fileName){
    AssetManager am = context.getAssets();
    try {
        InputStream is = am.open(fileName);
        return is;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public static String loadContentFromFile(Context context, String path){
    String content = null;
    try {
        InputStream is = loadInputStreamFromAssetFile(context, path);
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        content = new String(buffer, "UTF-8");
    } catch (IOException ex) {
        ex.printStackTrace();
        return null;
    }
    return content;
}

अब आप फॉलो को कॉल करके सामग्री प्राप्त कर सकते हैं

String json= FileUtil.loadContentFromFile(context, "data.json");

Data.json को ध्यान में रखते हुए Application \ app \ src \ main \ परिसंपत्तियों \ data.json पर संग्रहीत किया जाता है


3

MainActivity.java में

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tvView = (TextView) findViewById(R.id.tvView);

        AssetsReader assetsReader = new AssetsReader(this);
        if(assetsReader.getTxtFile(your_file_title)) != null)
        {
            tvView.setText(assetsReader.getTxtFile(your_file_title)));
        }
    }

इसके अलावा, आप अलग-अलग वर्ग बना सकते हैं जो सभी काम करता है

public class AssetsReader implements Readable{

    private static final String TAG = "AssetsReader";


    private AssetManager mAssetManager;
    private Activity mActivity;

    public AssetsReader(Activity activity) {
        this.mActivity = activity;
        mAssetManager = mActivity.getAssets();
    }

    @Override
    public String getTxtFile(String fileName)
    {
        BufferedReader reader = null;
        InputStream inputStream = null;
        StringBuilder builder = new StringBuilder();

        try{
            inputStream = mAssetManager.open(fileName);
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;

            while((line = reader.readLine()) != null)
            {
                Log.i(TAG, line);
                builder.append(line);
                builder.append("\n");
            }
        } catch (IOException ioe){
            ioe.printStackTrace();
        } finally {

            if(inputStream != null)
            {
                try {
                    inputStream.close();
                } catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }

            if(reader != null)
            {
                try {
                    reader.close();
                } catch (IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }
        }
        Log.i(TAG, "builder.toString(): " + builder.toString());
        return builder.toString();
    }
}

मेरी राय में यह एक इंटरफ़ेस बनाने के लिए बेहतर है, लेकिन यह neccessary नहीं है

public interface Readable {
    /**
     * Reads txt file from assets
     * @param fileName
     * @return string
     */
    String getTxtFile(String fileName);
}

2

यदि आप गतिविधि के अलावा किसी अन्य वर्ग का उपयोग करते हैं, तो आप ऐसा करना चाहते हैं,

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( YourApplication.getInstance().getAssets().open("text.txt"), "UTF-8"));

2

कोटलिन का उपयोग करके, आप Android में संपत्ति से एक फ़ाइल पढ़ने के लिए निम्न कार्य कर सकते हैं:

try {
    val inputStream:InputStream = assets.open("helloworld.txt")
    val inputString = inputStream.bufferedReader().use{it.readText()}
    Log.d(TAG,inputString)
} catch (e:Exception){
    Log.d(TAG, e.toString())
}

2

हो सकता है कि बहुत देर हो चुकी हो, लेकिन दूसरों के लिए जो आड़ू के जवाब की तलाश में हैं:

public static String loadAssetFile(Context context, String fileName) {
    try {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(context.getAssets().open(fileName)));
        StringBuilder out= new StringBuilder();
        String eachline = bufferedReader.readLine();
        while (eachline != null) {
            out.append(eachline);
            eachline = bufferedReader.readLine();
        }
        return out.toString();
    } catch (IOException e) {
        Log.e("Load Asset File",e.toString());
    }
    return null;
}

1

cityfile.txt

   public void getCityStateFromLocal() {
        AssetManager am = getAssets();
        InputStream inputStream = null;
        try {
            inputStream = am.open("city_state.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
        ObjectMapper mapper = new ObjectMapper();
        Map<String, String[]> map = new HashMap<String, String[]>();
        try {
            map = mapper.readValue(getStringFromInputStream(inputStream), new TypeReference<Map<String, String[]>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        ConstantValues.arrayListStateName.clear();
        ConstantValues.arrayListCityByState.clear();
        if (map.size() > 0)
        {
            for (Map.Entry<String, String[]> e : map.entrySet()) {
                CityByState cityByState = new CityByState();
                String key = e.getKey();
                String[] value = e.getValue();
                ArrayList<String> s = new ArrayList<String>(Arrays.asList(value));
                ConstantValues.arrayListStateName.add(key);
                s.add(0,"Select City");
                cityByState.addValue(s);
                ConstantValues.arrayListCityByState.add(cityByState);
            }
        }
        ConstantValues.arrayListStateName.add(0,"Select States");
    }
 // Convert InputStream to String
    public String getStringFromInputStream(InputStream is) {
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String line;
        try {
            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb + "";

    }

लिंक अब लौटता हैFile no longer available That file has now been permanently removed and cannot be recovered
gregn3

1

स्कैनर वर्ग इसे सरल कर सकता है।

        StringBuilder sb=new StringBuilder();
        Scanner scanner=null;
        try {
            scanner=new Scanner(getAssets().open("text.txt"));
            while(scanner.hasNextLine()){
                sb.append(scanner.nextLine());
                sb.append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(scanner!=null){try{scanner.close();}catch (Exception e){}}
        }
        mTextView.setText(sb.toString());

आप इन 2 लाइनों को मर्ज कर सकते हैं sb.append (scanner.nextLine ()); sb.append ( '\ n'); to sb.appendln (scanner.nextLine ());
मोजतबा

0

@HpTerm उत्तर कोटलिन संस्करण:

private fun getDataFromAssets(): String? {

    var bufferedReader: BufferedReader? = null
    var data: String? = null

    try {
        bufferedReader = BufferedReader(
            InputStreamReader(
                activity?.assets?.open("Your_FILE.html"),     
                "UTF-8"
            )
        )                  //use assets? directly if in activity

       var mLine:String = bufferedReader?.readLine()
        while (mLine != null) {
            data+= mLine
            mLine=bufferedReader.readLine()
        }

    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        try {
            bufferedReader?.close()
        } catch (e: Exception) {
           e.printStackTrace()
        }
    }
    return data
}

वर्तमान में यह स्ट्रिंग को अशक्त कर देगा। आवश्यक परिवर्तन: var mLine:Stringहोना चाहिए var mLine:String? var data: String?होना चाहिए var data = ""वापसी प्रकार होना चाहिएString
fupduck

0

यहाँ एक फ़ोल्डर InputStreamमें एक फ़ाइल के लिए प्राप्त करने का एक तरीका assetsहै Context, बिना Activity, Fragmentया Application। उससे आपको डेटा कैसे मिलेगाInputStream यह आपके ऊपर है। यहाँ अन्य उत्तरों में इसके लिए बहुत सारे सुझाव हैं।

Kotlin

val inputStream = ClassLoader::class.java.classLoader?.getResourceAsStream("assets/your_file.ext")

जावा

InputStream inputStream = ClassLoader.class.getClassLoader().getResourceAsStream("assets/your_file.ext");

यदि कोई प्रथा चलन में है तो सभी दांव बंद हो जाते ClassLoaderहैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.