ZOFTINO.COM android and web dev tutorials

Saving Files to Internal Storage & External Storage in Android

Certain types of applications need to save data in files on device internal or external storage. You can read from and write to files in android file system using Files API. Before we jump into details, let’s see other available local storage options in android. It is important to understand all storage options so that you choose the right option that doesn’t impact performance and user experience.

There are other options to save data locally such as shared preference and SQLite database. Shared preference lets you save primitive data as key value pairs. If you have structured data that need to be stored locally, the best option would be SQLite database. You can get more information on saving data as key value pair and in SQLite database by reading my previous posts shared preferences and SQLite database.

Saving Files to Internal Storage

Files stored in internal storage are private to app. Files are removed when app is uninstalled. If you want to keep file private and can be accessed within the app only, then internal storage is the right option. Reading and writing operations on files in internal storage don’t require any permission from user.

To create a file to internal storage, first you need to get directory. There are two types of directories, temporary cache directory and directory for permanent files. Files stored in temporary directory are removed by the system to free up storage space. To get internal directory for your app, call getFilesDir(). To get cache directory, call getCacheDir() methd. Once you have directory location, you can create, write and read files using Files APi.

There is another way to create files, using Context’s method openFileOutput() which takes file name and mode arguments. Once you have output stream you can write content to it as shown below.

 FileOutputStream outputStream;

try {
    if (update) {
        outputStream = openFileOutput(fileName, Context.MODE_APPEND);
    } else {
        outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
    }
    outputStream.write(content.getBytes());
    outputStream.flush();
    outputStream.close();
 

Saving Files to External Storage

External storage is the best option to save files on when you want to share files with other apps. When you uninstall an app, files associated with the app which are stored on external storage get deleted only if you save files in the directory returned by getExternalFilesDir(). You need below permissions to read and write files to external storage.

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

The first step in writing and reading files on external storage is to check for the availability of external storage. You can do so, by calling Environment.getExternalStorageState() method. This method returns state of external storage.

To save files in a public folder, which are accessible by other apps, you need to call Environment’s getExternalStoragePublicDirectory() method passing directory such as DIRECTORY_DOCUMENTS, DIRECTORY_DOWNLOADS, DIRECTORY_MOVIES or other pubic folder, you can find the public directory constants in Environment class. To save file in your app private folder, you need to call getExternalFilesDir()

 if (!Environment.MEDIA_MOUNTED.equals(state)) {
    return;
}
File file = new File(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_DOCUMENTS), filenameExternal);
 

Saving Files to Internal Storage & External Storage Complete Code

Activity

package com.zoftino.content;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadWriteFilesActivity extends AppCompatActivity {

    private final String filenameInternal = "couponsFile";
    private final String filenameExternal = "cashbackFile";
    private TextView tv;

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

        tv = (TextView) findViewById(R.id.file_info);
    }

    public void writeFileInternalStorage(View view) {
        String coupons = "Get upto 20% off mobile @ xyx shop \n Get upto 30% off on appliances @ yuu shop";
        createUpdateFile(filenameInternal, coupons, false);
    }

    public void appendFileInternalStorage(View view) {
        String coupons = "Get upto 50% off fashion @ xyx shop \n Get upto 80% off on beauty @ yuu shop";
        createUpdateFile(filenameInternal, coupons, true);
    }

    private void createUpdateFile(String fileName, String content, boolean update) {
        FileOutputStream outputStream;

        try {
            if (update) {
                outputStream = openFileOutput(fileName, Context.MODE_APPEND);
            } else {
                outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
            }
            outputStream.write(content.getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void readFileInternalStorage(View view) {
        try {
            FileInputStream fileInputStream = openFileInput(filenameInternal);
            BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));

            StringBuffer sb = new StringBuffer();
            String line = reader.readLine();

            while (line != null) {
                sb.append(line);
                line = reader.readLine();
            }
            tv.setText(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void createTemporaryFile(View view) {
        try {
            String fileName = "couponstemp";
            String coupons = "Get upto 50% off shoes @ xyx shop \n Get upto 80% off on shirts @ yuu shop";

            File file = File.createTempFile(fileName, null, getCacheDir());

            FileOutputStream outputStream = new FileOutputStream(file);
            outputStream.write(coupons.getBytes());
            outputStream.flush();
            outputStream.close();

        } catch (IOException e) {
        }
    }

    public void deleteFile(View view) {
        try {
            String fileName = "couponstemp";
            File file = File.createTempFile(fileName, null, getCacheDir());

            file.delete();
        } catch (IOException e) {
        }
    }

    public void writeFileExternalStorage(View view) {
        String cashback = "Get 2% cashback on all purchases from xyz \n Get 10% cashback on travel from dhhs shop";
        String state = Environment.getExternalStorageState();
        //external storage availability check
        if (!Environment.MEDIA_MOUNTED.equals(state)) {
            return;
        }
        File file = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_DOCUMENTS), filenameExternal);


        FileOutputStream outputStream = null;
        try {
            file.createNewFile();
            //second argument of FileOutputStream constructor indicates whether to append or create new file if one exists
            outputStream = new FileOutputStream(file, true);

            outputStream.write(cashback.getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Activity layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_rwfiles"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.zoftino.content.ReadWriteFilesActivity">
    <TextView
        android:id="@+id/file_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"></TextView>

    <Button
        android:id="@+id/write_file"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="writeFileInternalStorage"
        android:text="Write File Internal Storage"></Button>
    <Button
        android:id="@+id/read_file"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="readFileInternalStorage"
        android:text="Read File Internal Storage"></Button>
    <Button
        android:id="@+id/append_file"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="appendFileInternalStorage"
        android:text="Append File"></Button>
    <Button
        android:id="@+id/temp_file"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="createTemporaryFile"
        android:text="Create Temp File"></Button>
    <Button
        android:id="@+id/delete_file"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="deleteFile"
        android:text="Delete File"></Button>
    <Button
        android:id="@+id/write_file_ext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="writeFileExternalStorage"
        android:text="Write File External Storage"></Button>
</LinearLayout>