Reading and Writing files in Android will be helpful if you want to read data from SD Card, store your application data as a text file. In this tutorial we are going to learn same. Below are some points that we are going to learn in today’s tutorial:
1. Write File – Write user input data into TextFile.
2. Read File – Read data from saved user data file.
3. Delete File – Delete saved file from SD Card.
4. TimeStamp – Fetching current time stamp and saved in shared preferences when file is saved.
5. File Path – Display file path to locate where the Text File is saved.
Prerequisites required for this tutorial –
We are going to use two classes for writing and reading file to SD Card –
1. FileWriter – A specialised Writer
that writes to a file in the file system. All write requests made by calling methods in this class are directly forwarded to the equivalent function of the underlying operating system. Since this may induce some performance penalty, in particular if many small write requests are made, a FileWriter is often wrapped by a BufferedWriter.
2. FileReader – A specialised Reader
that reads from a file in the file system. All read requests made by calling methods in this class are directly forwarded to the equivalent function of the underlying operating system. Since this may induce some performance penalty, in particular if many small read requests are made, a FileReader is often wrapped by a BufferedReader.
In this tutorial, we are going to learn how to write, read and delete File operations in Android.
1. Create a new project in Android Studio by navigating to File ⇒ New Android ⇒ Application Project and fill required details. By default my activity is MainActivity.java.
2. Open res=>values=strings.xml and add the following strings to it.
1 2 3 4 5 6 7 8 9 10 |
<resources> <string name="app_name">Read & Write TextFile Demo</string> <string name="mainTitle">Read & Write Text File</string> <string name="enterMessage">Enter your message below</string> <string name="saveMessage">Save Message to SD Card</string> <string name="readMessage">Read Message From SD Card</string> <string name="deleteMessage">Delete Message From SD Card</string> </resources> |
3. Create a xml layout naming activity_main.xml and add the following code. In this layout there is one EditText to take user input and some buttons for writing, reading and delete text file and a hidden layout for showing saved text file data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#eeeeee"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:gravity="center" android:padding="10dp" android:text="@string/mainTitle" android:textAllCaps="true" android:textColor="#3F51B5" android:textSize="19sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:padding="3dp" android:text="@string/enterMessage" android:textColor="#939393" android:textSize="15sp" /> <!-- Input your Message to be save in file --> <EditText android:id="@+id/enterMessage" android:layout_width="fill_parent" android:layout_height="180dp" android:background="@drawable/editttext_border" android:gravity="top|left" android:inputType="textCapSentences|textMultiLine" android:padding="5dp" android:scrollbars="vertical" android:textColor="#9e9e9e" android:textSize="16sp" /> <!-- Save Message Button --> <Button android:id="@+id/saveMessage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:background="#ffffff" android:elevation="5dp" android:text="@string/saveMessage" android:textColor="#2196F3" android:textSize="15sp" /> <!-- Read Message Button --> <Button android:id="@+id/readMessage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:background="#ffffff" android:elevation="5dp" android:text="@string/readMessage" android:textColor="#2196F3" android:textSize="15sp" /> <!-- Show Message Layout --> <RelativeLayout android:id="@+id/readMessageLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="7dp" android:visibility="gone"> <!-- TextView For displaying saved file path --> <TextView android:id="@+id/savedTextFileNameandPath" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/savedTextFileTime" android:gravity="left|center_vertical" android:padding="5dp" android:textColor="#009688" android:textSize="13sp" /> <!-- TextView For displaying saved file time --> <TextView android:id="@+id/savedTextFileTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:gravity="right|center_vertical" android:padding="5dp" android:textColor="#9e9e9e" android:textSize="12sp" /> <!-- TextView For displaying saved file data --> <TextView android:id="@+id/savedFileMessageBody" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@+id/savedTextFileNameandPath" android:gravity="center_vertical|left" android:padding="5dp" android:textColor="#616161" android:textSize="14sp" /> </RelativeLayout> <!-- Delete Message Button --> <Button android:id="@+id/deleteMessage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:background="#ffffff" android:elevation="5dp" android:text="@string/deleteMessage" android:textColor="#2196F3" android:textSize="15sp" /> </LinearLayout> </ScrollView> |
4. Create a drawable under drawable directory naming edittext_border.xml for giving border to EditText.
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#ffffff" /> <stroke android:width="1px" android:color="#9e9e9e" /> </shape> |
5. Create a CheckForSDCard.java class for checking if SDCard is mounted or not.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
com.read_write_textfile_demo; import android.os.Environment; public class CheckForSDCard { //Check If SD Card is present or not method public boolean isSDCardPresent() { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { return true; } return false; } } |
6. Now below are methods that i am using for writing , reading and deleting text files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//Method for writing data to text file private void saveMessageIntoSDCard(File savedFile, String messageBody) { try { //File writer is used for writing data FileWriter fWriter = new FileWriter(savedFile); fWriter.write(messageBody);//write data fWriter.flush();//flush writer fWriter.close();//close writer } catch (Exception e) { e.printStackTrace(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//Method that will return saved text file data after reading private String readMessageFromSDCard() { //First check if main directory is present or not if (!fileDirectory.exists()) Toast.makeText(getBaseContext(), "There is no main directory present. ", Toast.LENGTH_SHORT).show(); else { //Then check if text file is present or not File savedFile = new File(fileDirectory.getAbsolutePath() + "/" + FileName); if (!savedFile.exists()) Toast.makeText(getBaseContext(), "There is no such file to read data. ", Toast.LENGTH_SHORT).show(); else { //Finally read data using FileReader try { FileReader rdr = new FileReader(fileDirectory.getAbsolutePath() + "/" + FileName); char[] inputBuffer = new char[READ_BLOCK_SIZE];//get Block size as buffer String savedData = ""; int charRead = rdr.read(inputBuffer); //Read all data one by one by using loop and add it to string created above for (int k = 0; k < charRead; k++) { savedData += inputBuffer[k]; } return savedData;//return saved data } catch (Exception e) { e.printStackTrace(); Log.e("Message", e.getLocalizedMessage()); return null; } } } return null; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//Delete text file method private void deleteMessageFromSDCard() { //Check if main directory is present or not if (!fileDirectory.exists()) Toast.makeText(getBaseContext(), "There is no main directory present.", Toast.LENGTH_SHORT).show(); else { //Now Check if text file is present or not File savedFile = new File(fileDirectory.getAbsolutePath() + "/" + FileName); if (!savedFile.exists()) Toast.makeText(getBaseContext(), "There is no saved file present.", Toast.LENGTH_SHORT).show(); else { savedFile.delete();//If text file is present then delete file Toast.makeText(getBaseContext(), "File deleted Successfully.", Toast.LENGTH_SHORT).show(); } } } |
1 2 3 |
//Get Current Date and put it in Shared Preferences SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); String currentDateandTime = sdf.format(new Date()); |
7. Finally come to your MainActivity.java and add the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
package com.read_write_textfile_demo; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Environment; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static EditText enterMessage; private static Button saveMessage, readMessage, deleteMessage; private static TextView savedMessageFileNameandPath, savedMessageTime, saveMessageData; private static RelativeLayout readMessageLayout; private static File fileDirectory = null;//Main Directory File private static final String DirectoryName = "Androhub Saved Files";//Main Directory Name private static final String FileName = "androhub.txt";//Text File Name private static final int READ_BLOCK_SIZE = 512;//Block Size for text File //Preferences to Store TimStamp when data is Saved private static SharedPreferences timeSharedPreferences; private static SharedPreferences.Editor editor; //Preferences Name and KeyValue for TimeStamp private static final String SharedPreferencesName = "TimePreferences"; private static final String TimeKeyValue = "TimeKeyValue"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); setListeners(); } //Init All views private void initViews() { //Init shared preferences timeSharedPreferences = getSharedPreferences(SharedPreferencesName, Context.MODE_PRIVATE); editor = timeSharedPreferences.edit(); enterMessage = (EditText) findViewById(R.id.enterMessage); saveMessage = (Button) findViewById(R.id.saveMessage); readMessage = (Button) findViewById(R.id.readMessage); deleteMessage = (Button) findViewById(R.id.deleteMessage); savedMessageFileNameandPath = (TextView) findViewById(R.id.savedTextFileNameandPath); savedMessageTime = (TextView) findViewById(R.id.savedTextFileTime); saveMessageData = (TextView) findViewById(R.id.savedFileMessageBody); readMessageLayout = (RelativeLayout) findViewById(R.id.readMessageLayout); //Check if sd card is present or not if (new CheckForSDCard().isSDCardPresent()) { fileDirectory = new File( Environment.getExternalStorageDirectory() + "/" + DirectoryName); } else Toast.makeText(MainActivity.this, "SD Card is not present.", Toast.LENGTH_SHORT).show();//Show toast if SD Card is not mounted } //set listeners to buttons private void setListeners() { saveMessage.setOnClickListener(this); readMessage.setOnClickListener(this); deleteMessage.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.saveMessage: saveMessage(); break; case R.id.readMessage: showSavedFileData(readMessageFromSDCard()); break; case R.id.deleteMessage: deleteMessageFromSDCard(); break; } } //Call Save Message Method private void saveMessage() { String messageBody = enterMessage.getText().toString().trim();//get Input message //Check if it is null or not if (messageBody.length() == 0 && messageBody.equals("")) Toast.makeText(MainActivity.this, "Please Enter some message.", Toast.LENGTH_SHORT).show(); else { try { //Create Main Directory if not present if (!fileDirectory.exists()) fileDirectory.mkdir(); //Make File Name under main Directory File savedFile = new File(fileDirectory.getAbsolutePath() + "/" + FileName); //If Saved File exists then check if it's size is greater than 0 if (savedFile.exists()) { if (savedFile.length() > 0) appendOrOverrideSavedFile(savedFile, messageBody);//if file present then show alert for appending and overriding else { //else save data into file saveMessageIntoSDCard(savedFile, messageBody); Toast.makeText(getBaseContext(), "File saved successfully!", Toast.LENGTH_SHORT).show(); } } else { //If Saved file doesn't exists then create new file and save file saveMessageIntoSDCard(savedFile, messageBody); Toast.makeText(getBaseContext(), "File saved successfully!", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); Log.e("Message", e.getLocalizedMessage()); } } } //Method to show alert if file already present private void appendOrOverrideSavedFile(final File savedFile, final String message) { final String savedMessage = readMessageFromSDCard();//Read saved message //Check if saved message not null if (savedMessage != null && savedMessage.length() > 0 && !savedMessage.equals("")) { //If not null then show alert AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("Choose.."); builder.setMessage("What do you want to do with message?nnAppend data to current saved file or override saved data."); builder.setPositiveButton("OVERRIDE", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //If Override is selected then textfile data is overrided saveMessageIntoSDCard(savedFile, message); Toast.makeText(getBaseContext(), "File Overrided Successfully!", Toast.LENGTH_SHORT).show(); } }); builder.setNegativeButton("APPEND", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //If Append is selected then textfile data is appended with new data saveMessageIntoSDCard(savedFile, savedMessage + "nn" + message); Toast.makeText(getBaseContext(), "File Appended Successfully!", Toast.LENGTH_SHORT).show(); } }); builder.setNeutralButton("CANCEL", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); AlertDialog ad = builder.create(); ad.setCancelable(true); ad.setCanceledOnTouchOutside(true); ad.show(); } else //If there is nothing to read from saved fie then simply add data to file saveMessageIntoSDCard(savedFile, message); } //Method for writing data to text file private void saveMessageIntoSDCard(File savedFile, String messageBody) { try { //File writer is used for writing data FileWriter fWriter = new FileWriter(savedFile); fWriter.write(messageBody);//write data fWriter.flush();//flush writer fWriter.close();//close writer //Get Current Date and put it in Shared Preferences SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); String currentDateandTime = sdf.format(new Date()); editor.putString(TimeKeyValue, currentDateandTime); editor.commit(); } catch (Exception e) { e.printStackTrace(); } } //Method that will return saved text file data after reading private String readMessageFromSDCard() { //First check if main directory is present or not if (!fileDirectory.exists()) Toast.makeText(getBaseContext(), "There is no main directory present. ", Toast.LENGTH_SHORT).show(); else { //Then check if text file is present or not File savedFile = new File(fileDirectory.getAbsolutePath() + "/" + FileName); if (!savedFile.exists()) Toast.makeText(getBaseContext(), "There is no such file to read data. ", Toast.LENGTH_SHORT).show(); else { //Finally read data using FileReader try { FileReader rdr = new FileReader(fileDirectory.getAbsolutePath() + "/" + FileName); char[] inputBuffer = new char[READ_BLOCK_SIZE];//get Block size as buffer String savedData = ""; int charRead = rdr.read(inputBuffer); //Read all data one by one by using loop and add it to string created above for (int k = 0; k < charRead; k++) { savedData += inputBuffer[k]; } return savedData;//return saved data } catch (Exception e) { e.printStackTrace(); Log.e("Message", e.getLocalizedMessage()); return null; } } } return null; } //Show Saved data private void showSavedFileData(String savedMessage) { //Check if saved data is not null if (savedMessage != null && savedMessage.length() > 0 && !savedMessage.equals("")) { //Check if TimeStamp is present or not if (timeSharedPreferences.contains(TimeKeyValue)) savedMessageTime.setText(timeSharedPreferences.getString(TimeKeyValue, ""));//Dispaly saved timestamp savedMessageFileNameandPath.setText(FileName + " - inside '" + fileDirectory.getAbsolutePath() + "'");//Display file path saveMessageData.setText(savedMessage);//display saved data readMessageLayout.setVisibility(View.VISIBLE);//Make visible the read message layout } } //Delete text file method private void deleteMessageFromSDCard() { //Check if main directory is present or not if (!fileDirectory.exists()) Toast.makeText(getBaseContext(), "There is no main directory present.", Toast.LENGTH_SHORT).show(); else { //Now Check if text file is present or not File savedFile = new File(fileDirectory.getAbsolutePath() + "/" + FileName); if (!savedFile.exists()) Toast.makeText(getBaseContext(), "There is no saved file present.", Toast.LENGTH_SHORT).show(); else { savedFile.delete();//If text file is present then delete file readMessageLayout.setVisibility(View.GONE);//hide read file layout //Remove Saved TimeStamp editor.remove(TimeKeyValue); editor.commit(); Toast.makeText(getBaseContext(), "File deleted Successfully.", Toast.LENGTH_SHORT).show(); } } } } |
8. Finally, all done you can use above code to save your data in File.
Thanks.
Subscribe to us and get the latest news.
6 Comments
Bhushan
Tuesday, February 23rd, 2016Hi. Great tutorial. However, it does’t work on Android 6.0 due to changed in write permissions. Here’s a link to get an idea of how to implement write permissions:
http://stackoverflow.com/questions/33139754/android-6-0-marshmallow-cannot-write-to-sd-card
Can u please rewrite the code by using this? or at least guild me how to do it to make this app run on MM. Thanks.
Droid
Tuesday, February 23rd, 2016Hi Bhushan,
Do the below following steps for MarshMallow Device :
1. private static final int REQUEST_WRITE_STORAGE = 112;
declare this as global variable for Request Id.
2. While reading and writing on SD Card use this code before doing that task
boolean hasPermission = (ContextCompat.checkSelfPermission(activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
ActivityCompat.requestPermissions(parentActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
else{
//Call read or write method}
3. Now to access request permission that user is accepted to grant permission then use this method for acceptance and denial
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case REQUEST_WRITE_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//Call read or write method
} else
{
Toast.makeText(parentActivity, “The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission”, Toast.LENGTH_LONG).show();
}
}
}
}
Hope it helps.
Thanks
hassan
Friday, April 7th, 2017can you sent the coding for this tutorial.. i’m using android 6.0.. realy appreciate that.. tq
Dr. Droid
Saturday, April 8th, 2017Hi Hassan,
Please click on Download Source Code again. I replaced new code having Marshmallow permission. Hope it will help you.
Thanks
hashir
Wednesday, April 22nd, 2020Having issues in downloading the code. Its a 404
Dr. Droid
Thursday, May 7th, 2020Hi Hashir,
You can download the code from here: https://github.com/sonusurender/Read_Write_File_Operations_Demo
Thanks