Android'de Dosyadan / Dosyaya Dize Okuma / Yazma


213

EditText girilen metin alarak bir dosyayı dahili depolama birimine kaydetmek istiyorum. Sonra aynı dosyayı girilen metni String formunda döndürmek ve daha sonra kullanılacak başka bir String kaydetmek istiyorum.

İşte kod:

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

İşlemlerin nerede yapılmasını istediğim / değişkenlerin nerede kullanıldığına dair puanlarımı daha ayrıntılı analiz etmenize yardımcı olacak yorumlar ekledim.


2
soru "dosyadan / dosyaya nasıl okunur / yazılır?"
Dmitri Gudkov

Dizelerinizi saklamak için uygulamanın tercihlerini kullanmayı düşündünüz mü?
sdabet

4
BTW, depolama ile çalışmak için ana dosyaya izin verdiğinizden emin olun ...
Dmitri Gudkov

Bu uygulamak için birçok değişiklik ile benim yarı tam app. Benim fikrim, kullanıcının uygulamanın ilk çalıştırılmasında kimliğini yalnızca bir kez girmesidir. Daha sonra uygulama, depolanan kimliğe kullanıcı uygulamayı çalıştırdığı kadar çok başvuruda bulunacaktır. İzinlerin tümü manifest'e eklenir.
Binbaşı Aly

Yanıtlar:


334

Umarım bu sizin için yararlı olabilir.

Dosya Yaz:

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

Dosyayı Oku:

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
Sınıf Etkinlik'ten uzatılmazsa, "openFileInput ()" yönteminin kullanımı şu şekilde olmalıdır: context.openFileInput ()
Behzad

11
Not: Yukarıdaki kod iyi çalışır, ancak sonuçta elde edilen Dize dosyadan satır satırlarını içermez. Tekrar çizgi eklemek için "stringBuilder.append (receString);" "stringBuilder.append (takeString) .append (" \ n ");" olarak ayarlayın. Diğer satır sonu karakterlerini bekliyorsanız (örneğin, Windows metin dosyalarında \ r vb. Olacaktır), son dizenizde bunu biraz daha uyarlamanız gerekir.
treesAreEverywhere

26
Bu yapılandırma dosyası gerçek cihaza nerede kaydeder? kontrol etmek için bulamadım :(
Mehdi

4
Bence, kapanış akışları final@SharkAlley yanıtı gibi blokta olmalıdır
Yurii K

4
@Kenji dosya uygulamanın dosya dizinine kaydedilir (yani / data / data / <package_name> /files/config.txt). Uygulamanın işlemi buna erişebilir, ancak işletim sistemindeki tüm işlemlere erişemez. Uygulama, cihazınızın hangi android sürümünün çalıştığına bağlı olarak değişebilir. AOSP'nin uygulamasını çevrimiçi olarak kontrol edebilirsiniz. Örneğin, android 8.1_r5 için: android.googlesource.com/platform/frameworks/base/+/…
vhamon

188

Dosyaya bir dize okumak ve yazmak için genel bir strateji arayanlar için:

İlk olarak bir dosya nesnesi edinin

Depolama yoluna ihtiyacınız olacak. Dahili depolama için şunları kullanın:

File path = context.getFilesDir();

Harici depolama (SD kart) için şunları kullanın:

File path = context.getExternalFilesDir(null);

Ardından dosya nesnenizi oluşturun:

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

Dosyaya bir dize yazma

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

Veya Google Guava ile

Dize içeriği = Files.toString (dosya, StandardCharsets.UTF_8);

Dosyayı bir dizeye okuyun

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

Veya Google Guava kullanıyorsanız

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

Tamlık için bahsedeceğim

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

hiçbir kitaplık gerektirmez, ancak diğer seçeneklerden% 50 -% 400 daha yavaştır (Nexus 5 cihazımdaki çeşitli testlerde).

notlar

Bu stratejilerin her biri için bir IOException yakalamanız istenir.

Android'de varsayılan karakter kodlaması UTF-8'dir.

Harici depolama alanı kullanıyorsanız manifest'inize aşağıdakileri de eklemeniz gerekir:

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

veya

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

Yazma izni okuma izni anlamına gelir, bu nedenle her ikisine de ihtiyacınız yoktur.


Tamam örneğin bir kullanıcının tüm yayınlarını görmesini istiyorum ve başka bir ekrana gittiğinde ve geri geldiğinde, tekrar çizmem gerekiyor mu yoksa önbelleğe alınmış olduğundan sadece önbellekten çıkarıyor ve gösteriyorsa, sadece dışarı çeker, nasıl benim sunucuları sorgulamak değil demek için bir koşullu ekleyebilirim
Lion789

4
Böyle yapma new File(path + "/my-file-name.txt");. Bu duygunun çoğuna meydan okur File. new File(path, "my-file-name.txt");Bunun yerine kullanın .
JimmyB

@HannoBinder Android her zaman Linux üzerinde çalışır, bu nedenle ayırıcı "/" olarak garanti edilir. Bu bağlamda yeni File (path, "my-file-name.txt") kullanmanın yararı nedir? (Bunun bir nedeni varsa cevabı güncellemekten mutluluk duyuyorum.)
SharkAlley

1
Filebir sebep var mı? Senin durumunda, ben de atlamak Fileve sadece yapmak new FileInputStream(path + "/my-file-name.txt");, hangi tavsiye etmiyorum. ( Örneğin pathbir iz /
sürüyorsa

Öneri başına düzenlenmiştir. Thanks :)
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
Uygulama!? ne olması gerekiyordu?
alap

@alap @Eugene uygulama içeriğini statik olarak almak için kullanıyor. Bunun için ona ihtiyacı var context.getFilesDir(). Yerine new File(context.getFilesDir(), fileName)bir Filenesneyi ya da bir Stringişleve iletilen yerine geçebilirsiniz fileName.
lorenzo-s

7

Daha fazla performans için bir dosya yönteminden dize okunurken yapılan değişiklikler

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

aşağıdaki kodu kontrol edin.

Dosya sistemindeki bir dosyadan okuma.

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

Aşağıdaki kod dosyayı dahili dosya sistemine yazmaktır.

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

Bunun size yardımcı olacağını düşünüyorum.


3

Biraz acemiyim ve bugün işe yaramaya çalıştım.

Aşağıda bitirdiğim sınıf var. Çalışıyor ama çözümümün ne kadar kusurlu olduğunu merak ediyordum. Her neyse, bazılarınızın daha deneyimli halkın IO sınıfıma bakmaya ve bana bazı ipuçları vermeye istekli olabileceğini umuyordum. Şerefe!

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

Orada dosya yoksa, yeni bir dosya oluşturmanız gerekmez.
rml

1

ihtiyacımız olan ilk şey AndroidManifest.xml'deki izinlerdir

<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" />

bu yüzden bir asyncTask Kotlin sınıfında, dosyanın oluşturulmasını ele alıyoruz

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

    }

Tabii ki Android'i Api 23'ün üzerinde kullanıyorsanız, cihaz belleğine yazmaya izin verme isteğini yerine getirmelisiniz. Böyle bir şey

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

ardından bir etkinlikte çağrıyı yürütün.

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

bu dahili depolama izinleri geçersiz.
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
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.