Lese- / Schreibzeichenfolge von / in eine Datei in Android


213

Ich möchte eine Datei im internen Speicher speichern, indem ich den von EditText eingegebenen Text erhalte. Dann möchte ich, dass dieselbe Datei den eingegebenen Text in String-Form zurückgibt und in einem anderen String speichert, der später verwendet werden soll.

Hier ist der Code:

package com.omm.easybalancerecharge;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        final EditText num = (EditText) findViewById(R.id.sNum);
        Button ch = (Button) findViewById(R.id.rButton);
        TelephonyManager operator = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        String opname = operator.getNetworkOperatorName();
        TextView status = (TextView) findViewById(R.id.setStatus);
        final EditText ID = (EditText) findViewById(R.id.IQID);
        Button save = (Button) findViewById(R.id.sButton);

        final String myID = ""; //When Reading The File Back, I Need To Store It In This String For Later Use

        save.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                //Get Text From EditText "ID" And Save It To Internal Memory
            }
        });
        if (opname.contentEquals("zain SA")) {
            status.setText("Your Network Is: " + opname);
        } else {
            status.setText("No Network");
        }
        ch.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                //Read From The Saved File Here And Append It To String "myID"


                String hash = Uri.encode("#");
                Intent intent = new Intent(Intent.ACTION_CALL);
                intent.setData(Uri.parse("tel:*141*" + /*Use The String With Data Retrieved Here*/ num.getText()
                        + hash));
                startActivity(intent);
            }
        });
    }

Ich habe Kommentare beigefügt, um Ihnen bei der weiteren Analyse meiner Punkte zu helfen, wo die Operationen ausgeführt werden sollen / Variablen verwendet werden sollen.


2
Die Frage ist "Wie lese / schreibe ich in / aus einer Datei?"
Dmitri Gudkov

Haben Sie darüber nachgedacht, die Einstellungen der App zum Speichern Ihrer Zeichenfolgen zu verwenden?
Sdabet

4
Übrigens, stellen Sie sicher, dass Sie der Mainfest-Datei die Erlaubnis geben, mit Speicher zu arbeiten ...
Dmitri Gudkov

Dies ist meine halbfertige App mit vielen zu implementierenden Änderungen. Meine Idee ist, dass der Benutzer die ID beim ersten Ausführen der App nur einmal eingibt. Dann verweist die App so oft auf diese gespeicherte ID, wie der Benutzer die App ausführt. Alle Berechtigungen werden dem Manifest hinzugefügt.
Major Aly

Antworten:


334

Hoffe, das könnte für Sie nützlich sein.

Datei schreiben:

private void writeToFile(String data,Context context) {
    try {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("config.txt", Context.MODE_PRIVATE));
        outputStreamWriter.write(data);
        outputStreamWriter.close();
    }
    catch (IOException e) {
        Log.e("Exception", "File write failed: " + e.toString());
    } 
}

Datei lesen:

private String readFromFile(Context context) {

    String ret = "";

    try {
        InputStream inputStream = context.openFileInput("config.txt");

        if ( inputStream != null ) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String receiveString = "";
            StringBuilder stringBuilder = new StringBuilder();

            while ( (receiveString = bufferedReader.readLine()) != null ) {
                stringBuilder.append("\n").append(receiveString);
            }

            inputStream.close();
            ret = stringBuilder.toString();
        }
    }
    catch (FileNotFoundException e) {
        Log.e("login activity", "File not found: " + e.toString());
    } catch (IOException e) {
        Log.e("login activity", "Can not read file: " + e.toString());
    }

    return ret;
}

43
Wenn die Klasse nicht von Activity erweitert wird, sollte die Verwendung der Methode "openFileInput ()" folgendermaßen aussehen: context.openFileInput ()
Behzad

11
Hinweis: Der obige Code funktioniert gut, aber der resultierende String enthält keine Zeilenumbrüche aus der Datei. Um erneut Zeilenumbrüche hinzuzufügen, ändern Sie die Zeile "stringBuilder.append (receiveString);" zu "stringBuilder.append (receiveString) .append (" \ n ");". Wenn Sie andere Zeilenumbruchzeichen erwarten (z. B. Windows-Textdateien haben \ r usw.), müssen Sie dies in Ihrer letzten Zeichenfolge etwas mehr anpassen.
BäumeAreEverywhere

26
Wo speichert diese Konfigurationsdatei auf einem realen Gerät? Ich konnte es nicht finden, um zu überprüfen :(
Mahdi

4
Ich denke, das Schließen von Streams sollte im finalBlock sein, wie in @SharkAlley Antwort
Yurii K

4
@ Kenji Die Datei wird im Dateiverzeichnis der App gespeichert (dh / data / data / <Paketname> /files/config.txt). Der Prozess der App kann darauf zugreifen, jedoch nicht alle Prozesse im Betriebssystem. Die Implementierung kann je nach Android-Version Ihres Geräts unterschiedlich sein. Sie können die Implementierung des AOSP online überprüfen. Zum Beispiel für Android 8.1_r5: android.googlesource.com/platform/frameworks/base/+/…
Vhamon

187

Für diejenigen, die nach einer allgemeinen Strategie zum Lesen und Schreiben eines Strings in eine Datei suchen:

Holen Sie sich zuerst ein Dateiobjekt

Sie benötigen den Speicherpfad. Verwenden Sie für den internen Speicher:

File path = context.getFilesDir();

Verwenden Sie für den externen Speicher (SD-Karte):

File path = context.getExternalFilesDir(null);

Dann erstellen Sie Ihr Dateiobjekt:

File file = new File(path, "my-file-name.txt");

Schreiben Sie eine Zeichenfolge in die Datei

FileOutputStream stream = new FileOutputStream(file);
try {
    stream.write("text-to-write".getBytes());
} finally {
    stream.close();
}

Oder mit Google Guava

Zeichenfolgeninhalt = Files.toString (Datei, StandardCharsets.UTF_8);

Lesen Sie die Datei in eine Zeichenfolge

int length = (int) file.length();

byte[] bytes = new byte[length];

FileInputStream in = new FileInputStream(file);
try {
    in.read(bytes);
} finally {
    in.close();
}

String contents = new String(bytes);   

Oder wenn Sie Google Guava verwenden

String contents = Files.toString(file,"UTF-8");

Der Vollständigkeit halber werde ich erwähnen

String contents = new Scanner(file).useDelimiter("\\A").next();

Dies erfordert keine Bibliotheken, aber Benchmarks 50% - 400% langsamer als die anderen Optionen (in verschiedenen Tests auf meinem Nexus 5).

Anmerkungen

Für jede dieser Strategien werden Sie aufgefordert, eine IOException abzufangen.

Die Standard-Zeichenkodierung unter Android ist UTF-8.

Wenn Sie externen Speicher verwenden, müssen Sie Ihrem Manifest Folgendes hinzufügen:

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

oder

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

Schreibberechtigung impliziert Leseberechtigung, sodass Sie nicht beide benötigen.


Ok, ich möchte zum Beispiel, dass ein Benutzer alle seine Beiträge sieht. Wenn er zu einem anderen Bildschirm wechselt und zurückkommt, muss ich ihn erneut zeichnen oder weil er zwischengespeichert ist, wird er einfach aus dem Cache gezogen und nur angezeigt, wenn er angezeigt wird zieht es einfach heraus, wie füge ich eine wenn Bedingung hinzu, um zu sagen, meine Server nicht abzufragen
Lion789

4
Mach es nicht so new File(path + "/my-file-name.txt");. Dies widerspricht viel dem Sinn von File. Verwenden Sie new File(path, "my-file-name.txt");stattdessen.
JimmyB

@HannoBinder Android läuft immer auf Linux, daher ist das Trennzeichen garantiert "/". Was wäre der Vorteil der Verwendung einer neuen Datei (Pfad "my-file-name.txt") in diesem Zusammenhang? (Ich bin froh, die Antwort zu aktualisieren, wenn es einen Grund dafür gibt.)
SharkAlley

1
Filegibt es aus einem Grund. In Ihrem Fall könnten Sie genauso gut überspringen Fileund einfach tun new FileInputStream(path + "/my-file-name.txt");, was ich nicht empfehle. (Was ist, wenn zum Beispiel pathein Trailing enthalten ist /?)
JimmyB

Nach Ihrem Vorschlag bearbeitet. Danke :)
SharkAlley

37
public static void writeStringAsFile(final String fileContents, String fileName) {
    Context context = App.instance.getApplicationContext();
    try {
        FileWriter out = new FileWriter(new File(context.getFilesDir(), fileName));
        out.write(fileContents);
        out.close();
    } catch (IOException e) {
        Logger.logError(TAG, e);
    }
}

public static String readFileAsString(String fileName) {
    Context context = App.instance.getApplicationContext();
    StringBuilder stringBuilder = new StringBuilder();
    String line;
    BufferedReader in = null;

    try {
        in = new BufferedReader(new FileReader(new File(context.getFilesDir(), fileName)));
        while ((line = in.readLine()) != null) stringBuilder.append(line);

    } catch (FileNotFoundException e) {
        Logger.logError(TAG, e);
    } catch (IOException e) {
        Logger.logError(TAG, e);
    } 

    return stringBuilder.toString();
}

7
App !? was soll es sein !?
Alap

@alap Wird von @Eugene verwendet, um den App-Kontext statisch abzurufen. Er braucht es für context.getFilesDir(). Sie können nur Vorkommen von new File(context.getFilesDir(), fileName)durch ein FileObjekt oder eine Stringübergebene Funktion anstelle von ersetzen fileName.
Lorenzo-s

7

Nur ein bisschen Änderungen beim Lesen von Zeichenfolgen aus einer Dateimethode für mehr Leistung

private String readFromFile(Context context, String fileName) {
    if (context == null) {
        return null;
    }

    String ret = "";

    try {
        InputStream inputStream = context.openFileInput(fileName);

        if ( inputStream != null ) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);               

            int size = inputStream.available();
            char[] buffer = new char[size];

            inputStreamReader.read(buffer);

            inputStream.close();
            ret = new String(buffer);
        }
    }catch (Exception e) {
        e.printStackTrace();
    }

    return ret;
}

6

Überprüfen Sie den folgenden Code.

Lesen aus einer Datei im Dateisystem.

FileInputStream fis = null;
    try {

        fis = context.openFileInput(fileName);
        InputStreamReader isr = new InputStreamReader(fis);
        // READ STRING OF UNKNOWN LENGTH
        StringBuilder sb = new StringBuilder();
        char[] inputBuffer = new char[2048];
        int l;
        // FILL BUFFER WITH DATA
        while ((l = isr.read(inputBuffer)) != -1) {
            sb.append(inputBuffer, 0, l);
        }
        // CONVERT BYTES TO STRING
        String readString = sb.toString();
        fis.close();

    catch (Exception e) {

    } finally {
        if (fis != null) {
            fis = null;
        }
    }

Der folgende Code dient zum Schreiben der Datei in das interne Dateisystem.

FileOutputStream fos = null;
    try {

        fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
        fos.write(stringdatatobestoredinfile.getBytes());
        fos.flush();
        fos.close();

    } catch (Exception e) {

    } finally {
        if (fos != null) {
            fos = null;
        }
    }

Ich denke, das wird dir helfen.


3

Ich bin ein bisschen ein Anfänger und hatte Mühe, dies heute zum Laufen zu bringen.

Unten ist die Klasse, mit der ich gelandet bin. Es funktioniert, aber ich habe mich gefragt, wie unvollkommen meine Lösung ist. Wie auch immer, ich hatte gehofft, dass einige von euch erfahreneren Leuten bereit sein könnten, einen Blick auf meine IO-Klasse zu werfen und mir einige Tipps zu geben. Prost!

public class HighScore {
    File data = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator);
    File file = new File(data, "highscore.txt");
    private int highScore = 0;

    public int readHighScore() {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            try {
                highScore = Integer.parseInt(br.readLine());
                br.close();
            } catch (NumberFormatException | IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            try {
                file.createNewFile();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
            e.printStackTrace();
        }
        return highScore;
    }

    public void writeHighScore(int highestScore) {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            bw.write(String.valueOf(highestScore));
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Sie müssen keine neue Datei erstellen, wenn dort keine Datei vorhanden ist.
rml

1

Das erste, was wir brauchen, sind die Berechtigungen in AndroidManifest.xml

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

In einer asyncTask Kotlin-Klasse behandeln wir die Erstellung der Datei

    import android.os.AsyncTask
    import android.os.Environment
    import android.util.Log
    import java.io.*
    class WriteFile: AsyncTask<String, Int, String>() {
        private val mFolder = "/MainFolder"
        lateinit var folder: File
        internal var writeThis = "string to cacheApp.txt"
        internal var cacheApptxt = "cacheApp.txt"
        override fun doInBackground(vararg writethis: String): String? {
            val received = writethis[0]
            if(received.isNotEmpty()){
                writeThis = received
            }
            folder = File(Environment.getExternalStorageDirectory(),"$mFolder/")
            if(!folder.exists()){
                folder.mkdir()
                val readME = File(folder, cacheApptxt)
                val file = File(readME.path)
                val out: BufferedWriter
                try {
                    out = BufferedWriter(FileWriter(file, true), 1024)
                    out.write(writeThis)
                    out.newLine()
                    out.close()
                    Log.d("Output_Success", folder.path)
                } catch (e: Exception) {
                    Log.d("Output_Exception", "$e")
                }
            }
            return folder.path

    }

        override fun onPostExecute(result: String) {
            super.onPostExecute(result)

            if(result.isNotEmpty()){
                //implement an interface or do something
                Log.d("onPostExecuteSuccess", result)
            }else{
                Log.d("onPostExecuteFailure", result)
            }
        }

    }

Wenn Sie Android über Api 23 verwenden, müssen Sie natürlich die Anforderung bearbeiten, um das Schreiben in den Gerätespeicher zu ermöglichen. Etwas wie das

    import android.Manifest
    import android.content.Context
    import android.content.pm.PackageManager
    import android.os.Build
    import androidx.appcompat.app.AppCompatActivity
    import androidx.core.app.ActivityCompat
    import androidx.core.content.ContextCompat

    class ReadandWrite {
        private val mREAD = 9
        private val mWRITE = 10
        private var readAndWrite: Boolean = false
        fun readAndwriteStorage(ctx: Context, atividade: AppCompatActivity): Boolean {
            if (Build.VERSION.SDK_INT < 23) {
                readAndWrite = true
            } else {
                val mRead = ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE)
                val mWrite = ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)

                if (mRead != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(atividade, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), mREAD)
                } else {
                    readAndWrite = true
                }

                if (mWrite != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(atividade, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), mWRITE)
                } else {
                    readAndWrite = true
                }
            }
            return readAndWrite
        }
    }

Führen Sie dann in einer Aktivität den Aufruf aus.

  var pathToFileCreated = ""
    val anRW = ReadandWrite().readAndwriteStorage(this,this)
    if(anRW){
        pathToFileCreated =  WriteFile().execute("onTaskComplete").get()
        Log.d("pathToFileCreated",pathToFileCreated)
    }

Diese internen Speicherberechtigungen sind ungültig.
Lerk

0

Kotlin

class FileReadWriteService {

    private var context:Context? = ContextHolder.instance.appContext

    fun writeFileOnInternalStorage(fileKey: String, sBody: String) {
        val file = File(context?.filesDir, "files")
        try {
            if (!file.exists()) {
                file.mkdir()
            }
            val fileToWrite = File(file, fileKey)
            val writer = FileWriter(fileToWrite)
            writer.append(sBody)
            writer.flush()
            writer.close()
        } catch (e: Exception) {
            Logger.e(classTag, e)
        }
    }

    fun readFileOnInternalStorage(fileKey: String): String {
        val file = File(context?.filesDir, "files")
        var ret = ""
        try {
            if (!file.exists()) {
                return ret
            }
            val fileToRead = File(file, fileKey)
            val reader = FileReader(fileToRead)
            ret = reader.readText()
            reader.close()
        } catch (e: Exception) {
            Logger.e(classTag, e)
        }
        return ret
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.