2013-04-19 10 views
43

Ich möchte den Inhalt einer Datei in den Assets als String lesen. Zum Beispiel befindet sich ein Textdokument in src/main/assets/Assets Datei als String lesen

Original Question
ich, dass diese Frage gefunden meistens als ‚FAQ‘ verwendet wird, um ein Vermögen Datei zu lesen, deshalb zusammengefasst ich die obige Frage. Im Folgenden meine ursprüngliche naive Frage ist

Ich versuche, ein Vermögen Datei als Zeichenfolge zu lesen, habe ich versucht, wie 20 Antworten hier, aber sie für mich nicht funktionieren.

Ich habe eine Datei in meinem Assets-Ordner: data.opml, und ich muss den Inhalt in eine Zeichenfolge einfügen. Ich schicke es mag:

OPML.importFromFile(string, MainTabActivity.this); 

Und erhalten sie mag:

importFromFile(String filename, Context context); 

Etwas, das funktioniert hat (aber es ist kein Vermögen Datei):

OPML.importFromFile(new StringBuilder(Environment.getExternalStorageDirectory().toString()).append(File.separator).append(fileNames[which]).toString(),MainTabActivity.this); 

Ich habe versucht:

AssetFileDescriptor descriptor = getAssets().openFd("data.opml"); 
FileReader reader = new FileReader(descriptor.getFileDescriptor()); 
And also: 
InputStream input = getAssets().open("data.opml"); 
Reader reader = new InputStreamReader(input, "UTF-8"); 

Maby Ich mache etwas falsch, aber ich t wird einfach nicht funktionieren, weil es im Projekt Fehler gibt (bzw.: OPML ist nicht in der Lage für die Argumente Filereader und Reader), Wenn jemand weiß, wie man das macht, wäre es sehr zu schätzen!

Antwort

99

getAssets().open() wird eine InputStream zurückgeben. Lesen Sie von dieser unter Verwendung von Standard Java I/O:

StringBuilder buf=new StringBuilder(); 
    InputStream json=getAssets().open("book/contents.json"); 
    BufferedReader in= 
     new BufferedReader(new InputStreamReader(json, "UTF-8")); 
    String str; 

    while ((str=in.readLine()) != null) { 
     buf.append(str); 
    } 

    in.close(); 

Und in Zukunft, bitte erläutern vollständig und genau, was Sie mit „nicht funktionieren“, wie diese Erklärung nicht sehr hilfreich ist.

+0

Vielen Dank! Aber (es ist wahrscheinlich wieder ich) Ich kann es nicht mit OPML.importFromFile (xxx, MainTabActivity.this) arbeiten; und xxx ersetzt durch buf oder in (Ist nicht in der Lage für die argumente stringbuilder (und für in bufferedreader)) – Mdlc

+3

@ Mark029348: "kann es nicht zur arbeit bringen" ist eine nutzlose aussage, wie war "nicht funktionieren" in ihrem Frage. Solange du nicht erklärst, was du meinst, wird es sehr schwierig sein, dir weiter zu helfen. – CommonsWare

+0

@ Mark029348: Ich weiß nicht, wo diese 'OPML' Klasse herkommt. Der Methodenname weist darauf hin, dass eine Datei im Dateisystem erwartet wird. In diesem Fall können Sie kein Asset verwenden (außer vielleicht, indem Sie das Asset in eine Datei kopieren und dann einen Pfad an die Datei an "OPML" übergeben). Wenn es eine Methode gibt, die stattdessen den eigentlichen "String" des OPML-Texts verwendet, verwenden Sie diesen. In dem Codeausschnitt, den ich zeige, wird der 'String' durch Aufrufen von' toString() 'auf dem' StringBuilder' erhalten. – CommonsWare

28

Es gibt einen kleinen Fehler CommonsWare-Code - Zeilenumbruchzeichen werden verworfen und nicht zum String hinzugefügt. Hier ist ein fester Code zum Kopieren und Einfügen:

private String loadAssetTextAsString(Context context, String name) { 
     BufferedReader in = null; 
     try { 
      StringBuilder buf = new StringBuilder(); 
      InputStream is = context.getAssets().open(name); 
      in = new BufferedReader(new InputStreamReader(is)); 

      String str; 
      boolean isFirst = true; 
      while ((str = in.readLine()) != null) { 
       if (isFirst) 
        isFirst = false; 
       else 
        buf.append('\n'); 
       buf.append(str); 
      } 
      return buf.toString(); 
     } catch (IOException e) { 
      Log.e(TAG, "Error opening asset " + name); 
     } finally { 
      if (in != null) { 
       try { 
        in.close(); 
       } catch (IOException e) { 
        Log.e(TAG, "Error closing asset " + name); 
       } 
      } 
     } 

     return null; 
    } 
+0

Bitte verwenden Sie nicht den finally block um Ressourcen freizugeben. Finalizer sind nach Spezifikation unzuverlässig. Lesen Sie http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7 –

+1

tl; dr - warum nicht, wann gilt das, was stattdessen? –

+1

Verlassen Sie sich nicht auf den Finalize-Block, um den BufferedReader zu schließen. Schließen Sie es im Testblock selbst. Betrachten Sie nur als Sicherheitsnetz abgeschlossen. –

4

Sie können es auch tun, ohne Schleifen zu verwenden. Es ist ziemlich einfach

AssetManager assetManager = getAssets(); 
InputStream input; 
String text = ""; 

    try { 
     input = assetManager.open("test.txt"); 

     int size = input.available(); 
     byte[] buffer = new byte[size]; 
     input.read(buffer); 
     input.close(); 

     // byte buffer into a string 
     text = new String(buffer); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    Log.v("TAG", "Text File: " + text); 
+1

Ich glaube nicht, dass Sie die verfügbare() Methode so verwenden können. Siehe . – realh

+0

in der Praxis kann available() nur für kleine Dateien funktionieren, die auf SO I/O-Puffer passen. – Renascienza

+0

Es könnte unter bestimmten Umständen in der Praxis funktionieren, aber ich würde es hassen, der Entwickler zu sein, der den Fehler finden und beheben muss, der nur passiert, wenn Ihre Datei etwas zu groß ist. –

Verwandte Themen