Baca / Tulis String dari / ke File di Android

213

Saya ingin menyimpan file ke penyimpanan internal dengan memasukkan teks yang dimasukkan dari EditText. Lalu saya ingin file yang sama untuk mengembalikan teks yang dimasukkan dalam bentuk String dan menyimpannya ke String lain yang akan digunakan nanti.

Berikut kodenya:

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);
            }
        });
    }

Saya telah menyertakan komentar untuk membantu Anda menganalisis poin saya lebih lanjut tentang di mana saya ingin operasi dilakukan / variabel yang akan digunakan.

Mayor Aly
sumber
2
pertanyaannya adalah "bagaimana membaca / menulis ke / dari file?"
Dmitri Gudkov
Apakah Anda mempertimbangkan untuk menggunakan preferensi aplikasi untuk menyimpan string Anda?
sdabet
4
BTW, pastikan Anda memberi izin ke file mainfest, untuk beroperasi dengan penyimpanan ...
Dmitri Gudkov
Ini adalah aplikasi setengah lengkap saya dengan banyak perubahan untuk diterapkan. Ide saya adalah bahwa pengguna memasukkan ID hanya sekali pada saat pertama kali menjalankan aplikasi. Kemudian aplikasi akan mereferensikan ID yang disimpan tersebut sebanyak yang dilakukan pengguna menjalankan aplikasi. Izin semua ditambahkan ke manifes.
Mayor Aly

Jawaban:

334

Semoga ini bermanfaat bagi Anda.

Menulis file:

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());
    } 
}

Baca File:

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;
}
R9J
sumber
43
Jika kelas tidak diperluas dari Activity, penggunaan metode "openFileInput ()" harus seperti ini: context.openFileInput ()
Behzad
11
Catatan: Kode di atas berfungsi dengan baik, tetapi String yang dihasilkan tidak akan memuat linebreak apa pun dari file. Untuk menambahkan linebreak lagi, ubah baris "stringBuilder.append (acceptString);" ke "stringBuilder.append (acceptString) .append (" \ n ");". Jika Anda mengharapkan karakter linebreak lainnya (misalnya file teks Windows akan memiliki \ r dll.), Dalam string terakhir Anda, Anda harus mengadaptasinya sedikit lebih banyak.
treesAreEverywhere
27
di mana file konfigurasi ini disimpan di perangkat nyata? saya tidak dapat menemukannya untuk memeriksa :(
Mahdi
4
Saya pikir, menutup aliran harus di finalblok seperti dalam jawaban @SharkAlley
Yurii K
4
@ Kenji file disimpan di direktori file aplikasi (yaitu / data / data / <package_name> /files/config.txt). Proses aplikasi dapat mengaksesnya tetapi tidak semua proses di OS. Implementasinya mungkin berbeda tergantung pada versi android yang dijalankan perangkat Anda. Anda dapat memeriksa implementasi AOSP secara online. Misalnya, untuk android 8.1_r5: android.googlesource.com/platform/frameworks/base/+/…
vhamon
188

Bagi mereka yang mencari strategi umum untuk membaca dan menulis string ke file:

Pertama, dapatkan objek file

Anda akan memerlukan jalur penyimpanan. Untuk penyimpanan internal, gunakan:

File path = context.getFilesDir();

Untuk penyimpanan eksternal (kartu SD), gunakan:

File path = context.getExternalFilesDir(null);

Kemudian buat objek file Anda:

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

Tulis string ke file

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

Atau dengan Google Jambu

Isi string = Files.toString (file, StandardCharsets.UTF_8);

Baca file ke string

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);   

Atau jika Anda menggunakan Google Guava

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

Untuk kelengkapan saya akan menyebutkan

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

yang tidak memerlukan pustaka, tetapi tolok ukur 50% - 400% lebih lambat dari opsi lain (dalam berbagai tes pada Nexus 5 saya).

Catatan

Untuk masing-masing strategi ini, Anda akan diminta untuk menangkap IOException.

Pengkodean karakter default di Android adalah UTF-8.

Jika Anda menggunakan penyimpanan eksternal, Anda harus menambahkan manifes Anda:

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

atau

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

Izin menulis menyiratkan izin baca, jadi Anda tidak perlu keduanya.

SharkAlley
sumber
Ok misalnya saya ingin pengguna melihat semua postingnya, dan ketika dia pergi ke layar lain dan kembali, apakah saya perlu menggambar lagi atau karena di-cache hanya menariknya keluar dari cache dan hanya menunjukkannya, jika itu menunjukkan hanya menariknya keluar, bagaimana cara menambahkan syarat jika mengatakan tidak untuk meminta server saya
Lion789
4
Jangan lakukan itu seperti new File(path + "/my-file-name.txt");. Ini sangat menentang pengertian File. Gunakan new File(path, "my-file-name.txt");sebagai gantinya.
JimmyB
@HannoBinder Android selalu berjalan di atas Linux, sehingga pemisah dijamin menjadi "/". Apa manfaat menggunakan File baru (path, "my-file-name.txt") dalam konteks ini? (Saya senang memperbarui jawabannya jika ada alasan untuk itu.)
SharkAlley
1
Fileapakah ada karena suatu alasan. Dalam kasus Anda, Anda bisa saja melewati Filedan melakukannya new FileInputStream(path + "/my-file-name.txt");, yang saya tidak rekomendasikan. (Bagaimana jika pathberisi /
jejak
Diedit sesuai saran Anda. Terima kasih :)
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();
}
Eugene
sumber
7
Aplikasi !? apa yang seharusnya!?
alap
@alap Adalah sesuatu yang digunakan @Eugene untuk mengambil konteks aplikasi secara statis. Dia membutuhkannya untuk context.getFilesDir(). Anda bisa mengganti kemunculan new File(context.getFilesDir(), fileName)dengan Fileobjek atau Stringfungsi yang diteruskan alih-alih fileName.
lorenzo-s
7

Hanya sedikit modifikasi pada pembacaan string dari metode file untuk kinerja lebih

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;
}
Tai Le Anh
sumber
6

periksa kode di bawah ini.

Membaca dari file di sistem file.

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;
        }
    }

kode di bawah ini adalah untuk menulis file ke sistem file internal.

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;
        }
    }

Saya pikir ini akan membantu Anda.

Raj
sumber
3

Saya sedikit pemula dan berjuang untuk berhasil hari ini.

Di bawah ini adalah kelas yang saya ikuti. Ini bekerja tetapi saya bertanya-tanya seberapa tidak sempurna solusi saya. Bagaimanapun, saya berharap beberapa dari Anda yang lebih berpengalaman mungkin bersedia untuk melihat kelas IO saya dan memberi saya beberapa tips. Bersulang!

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();
        }
    }
}
Nihilarian
sumber
Anda tidak perlu membuat file baru jika tidak ada file di sana.
rml
1

hal pertama yang kita butuhkan adalah izin di 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" />

jadi di kelas Kotyn asyncTask, kami memperlakukan pembuatan file

    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)
            }
        }

    }

Tentu saja jika Anda menggunakan Android di atas Api 23, Anda harus menangani permintaan untuk memungkinkan penulisan ke memori perangkat. Sesuatu seperti ini

    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
        }
    }

lalu dalam suatu kegiatan, jalankan panggilan.

  var pathToFileCreated = ""
    val anRW = ReadandWrite().readAndwriteStorage(this,this)
    if(anRW){
        pathToFileCreated =  WriteFile().execute("onTaskComplete").get()
        Log.d("pathToFileCreated",pathToFileCreated)
    }
AllanRibas
sumber
izin penyimpanan internal tersebut tidak valid.
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
    }
}
Sazzad Hissain Khan
sumber