Wie man eine Datei von res / raw nach Namen liest

81

Ich möchte eine Datei aus dem Ordner res / raw / öffnen . Ich bin absolut sicher, dass die Datei existiert. Um die Datei zu öffnen habe ich versucht

File ddd = new File("res/raw/example.png");

Der Befehl

ddd.exists(); 

ergibt FALSE . Diese Methode funktioniert also nicht.

Ich versuche es

MyContext.getAssets().open("example.png");

endet in einer Ausnahme mit getMessage () "null".

Einfach benutzen

R.raw.example

ist nicht möglich, da der Dateiname nur zur Laufzeit als String bekannt ist.

Warum ist es so schwierig, auf eine Datei im Ordner / res / raw / zuzugreifen?

Bernd
quelle
Mögliches Duplikat von Dynamic Resource Loading Android
Simon
Warum ist es nur zur Laufzeit als String bekannt? Könnten Sie eine Zuordnung zwischen den Zeichenfolgen und den IDs beibehalten?
Kabuko
Lesen Sie die Dokumente: developer.android.com/guide/topics/resources/…
dmon
Danke für die Links. Ich werde eine korrekte Lösung als separate Antwort geben.
Bernd

Antworten:

145

Mit Hilfe der angegebenen Links konnte ich das Problem selbst lösen. Der richtige Weg ist, die Ressourcen-ID mit zu erhalten

getResources().getIdentifier("FILENAME_WITHOUT_EXTENSION",
                             "raw", getPackageName());

Um es als InputStream zu bekommen

InputStream ins = getResources().openRawResource(
            getResources().getIdentifier("FILENAME_WITHOUT_EXTENSION",
            "raw", getPackageName()));
Bernd
quelle
15
Nur zur Verdeutlichung: Stellen Sie den Dateinamen nicht voran raw/. Gültiges Beispiel: .getIdentifier("products","raw", getPackageName());fürres/raw/products.json
JJD
4
Wie von JJD angegeben, benötigen Sie das raw / vor dem FILENAME_WITHOUT_EXTENSION nicht. Ich habe festgestellt, dass ich, wenn Sie die Erweiterung verwenden möchten, zum Beispiel zwei Dateien abc.jpg und abc.zip, beide als abc_jpg und abc_zip zum Raw-Ordner hinzufügen werde (Erweiterungen im Raw-Ordner werden ignoriert) und dann die String-Variable zuweisen Dateiname = abc.jpg oder abc.zip, dann verwenden Sie InputStream ins = getResources (). openRawResource (getResources (). getIdentifier (Dateiname.replace (".", "_"), "raw", getPackageName ())); Hoffe das hilft jemandem :)
Bruce
Denken Sie daran, alle Streams zu schließen, die Sie öffnen
Pierre
Ich brauche den Dateipfad ... wie kann ich ihn anstelle des Eingabestreams erhalten?
Rafael Lima
44

Hier ist ein Beispiel für das Entnehmen einer XML-Datei aus einem Rohordner:

 InputStream XmlFileInputStream = getResources().openRawResource(R.raw.taskslists5items); // getting XML

Dann kannst du:

 String sxml = readTextFile(XmlFileInputStream);

wann:

 public String readTextFile(InputStream inputStream) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        byte buf[] = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buf)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {

        }
        return outputStream.toString();
    }
Emil Adz
quelle
1
Das Problem ist, dass ich R.raw.XYZ nicht verwenden kann, da der Name XYZ nur als Zeichenfolge verfügbar ist. Aber der Link von Simon hilft mir, das Problem zu lösen. Ich werde eine korrekte Lösung als separate Antwort geben.
Bernd
3
das funktioniert einwandfreiInputStream input = Context.getResources().openRawResource(R.raw.configjson);
Jemand irgendwo
13

Sie können Dateien in raw / res mit lesen getResources().openRawResource(R.raw.myfilename).

ABER es gibt eine IDE-Einschränkung, dass der von Ihnen verwendete Dateiname nur alphanumerische Kleinbuchstaben und Punkte enthalten darf. Daher werden Dateinamen wie XYZ.txtoder my_data.binnicht in R aufgeführt.

user2574545
quelle
9
Unterstrich ist auch in Ressourcendateinamen erlaubt
laalto
3
Auch Zahlen sind erlaubt (nicht als erstes Zeichen).
Phantômaxx
Nicht als erstes Zeichen ... weil das keine gültige Java-Variablenkennung wäre
peterchaula
1

Hier sind zwei Ansätze, mit denen Sie Rohstoffe mit Kotlin lesen können.

Sie können es erhalten, indem Sie die Ressourcen-ID abrufen. Sie können auch eine Zeichenfolgenkennung verwenden, in der Sie den Dateinamen inkrementell programmgesteuert ändern können.

Prost Kumpel 🎉

// R.raw.data_post

this.context.resources.openRawResource(R.raw.data_post)
this.context.resources.getIdentifier("data_post", "raw", this.context.packageName)
Morgan Koh
quelle