276

I want to save a file to the internal storage by getting the text inputted from EditText. Then I want the same file to return the inputted text in String form and save it to another String which is to be used later.

Here's the 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); } }); } 

I have included comments to help you further analyze my points as to where I want the operations to be done/variables to be used.

4
  • 2
    the question is "how to read/write to/from file?" Commented Jan 17, 2013 at 10:22
  • Did you consider using the app's preferences to store your strings ? Commented Jan 17, 2013 at 10:23
  • 5
    BTW, be sure you put permission to the mainfest file, to operate with storage... Commented Jan 17, 2013 at 10:24
  • 1
    This is my half complete app with many changes to implement. My idea is that the user enter the ID only once at the first run of the app. Then the app will reference that stored ID as many times as the user runs the app. Permissions are all added to the manifest. Commented Jan 17, 2013 at 10:28

11 Answers 11

405

Hope this might be useful to you.

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

Read 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; } 
Sign up to request clarification or add additional context in comments.

14 Comments

If the class is not extended from Activity, usage of the "openFileInput()" method should be like this: context.openFileInput()
Note: The code above works well, but the resulting String will not contain any of the linebreaks from the file. To add linebreaks again, change line "stringBuilder.append(receiveString);" to "stringBuilder.append(receiveString).append("\n");". If you expect other linebreak characters (e.g. Windows text files will have \r etc..), in your final string, you'll have to adapt this a bit more.
where this config file saves in real device? i could not find it to check :(
I think, closing streams should be in the final block as in @SharkAlley answer
@Kenji the file is saved in the app's file directory (i.e. /data/data/<package_name>/files/config.txt). The app's process can access to it but not all processes in the OS. The implementation might differ depending on which android version your device run. You can check the AOSP's implementation online. For example, for android 8.1_r5 : android.googlesource.com/platform/frameworks/base/+/…
|
232

For those looking for a general strategy for reading and writing a string to file:

First, get a file object

You'll need the storage path. For the internal storage, use:

File path = context.getFilesDir(); 

For the external storage (SD card), use:

File path = context.getExternalFilesDir(null); 

Then create your file object:

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

Write a string to the file

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

Or with Google Guava

String contents = Files.toString(file, StandardCharsets.UTF_8);

Read the file to a 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); 

Or if you are using Google Guava

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

For completeness I'll mention

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

which requires no libraries, but benchmarks 50% - 400% slower than the other options (in various tests on my Nexus 5).

Notes

For each of these strategies, you'll be asked to catch an IOException.

The default character encoding on Android is UTF-8.

If you are using external storage, you'll need to add to your manifest either:

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

or

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

Write permission implies read permission, so you don't need both.

4 Comments

Don't do it like new File(path + "/my-file-name.txt");. This defies much of the sense of File. Use new File(path, "my-file-name.txt"); instead.
@HannoBinder Android always runs on top of Linux, so the separator is guaranteed to be "/". What would be the benefit of using new File(path, "my-file-name.txt") in this context? (I'm happy to update the answer if there is a reason to.)
File is there for a reason. In your case, you could just as well skip File and just do new FileInputStream(path + "/my-file-name.txt");, which I don't recommend. (What if path contains a trailing / for example?)
This answer is outdated and should be removed.
49
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(); } 

2 Comments

App !? what does it supposed to be !?
@alap Is something @Eugene is using to retrieve app context statically. He need it for context.getFilesDir(). You can just replace occurrences of new File(context.getFilesDir(), fileName) with a File object or a String passed to function instead of fileName.
10

The Kotlin way by using builtin Extension function on File

Write: yourFile.writeText(textFromEditText)
Read: yourFile.readText()

1 Comment

Users should make sure how to properly define a readable/writable to use those functions, specially under Android platform.
8

Just a a bit modifications on reading string from a file method for more performance

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

Comments

7

check the below code.

Reading from a file in the filesystem.

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

below code is to write the file in to internal filesystem.

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

I think this will help you.

Comments

5

I'm a bit of a beginner and struggled getting this to work today.

Below is the class that I ended up with. It works but I was wondering how imperfect my solution is. Anyway, I was hoping some of you more experienced folk might be willing to have a look at my IO class and give me some tips. Cheers!

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

1 Comment

You do not need to create a new file if there is no file there.
4

the first thing we need is the permissions in AndroidManifest.xml

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

so in an asyncTask Kotlin class, we treat the creation of the 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) } } } 

Of course if you are using Android above Api 23, you must handle the request to allow writing to device memory. Something like this

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

then in an activity, execute the call.

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

1 Comment

those internal storage permissions are invalid.
3

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

Comments

2

We can use this code to write String to a file

public static void writeTextToFile(final String filename, final String data) { File file = new File(filename); try { FileOutputStream stream = new FileOutputStream(file); stream.write(data.getBytes()); stream.close(); } catch (IOException e) { e.printStackTrace(); } } 

Then in the Main code, we use this, for example

writeTextToFile(getExternalFilesDir("/").getAbsolutePath() + "/output.txt", "my-example-text"); 

After that, check the file at Android/data/<package-name>/files.

Comments

-2

In kotlin, The easiest way to append to a text file in kotlin:

val directory = File(context.filesDir, "LogsToSendToNextMunich").apply { mkdirs() } val file = File(directory,"Logs.txt") file.appendText("You new text") 

If you want to just write to the file:

yourFile.writeText("You new text") 

writing anything to the files, using bytes:

FileOutputStream(file).use { it.write("Some text for example".encodeToByteArray()) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.