Android Studio open failed: EROFS (Read-only file system) when creating a File

Claudiu Haidu picture Claudiu Haidu · May 23, 2015 · Viewed 24.5k times · Source

I know this question has been asked before, but I can't make it to work. Please help. I added the external storage permission, why is it still read-only?

public class MainActivity extends Activity {

    public static final String LOGTAG="EXPLORECA";
    public static final String USERNAME="pref_username";
    public static final String VIEWIMAGE="pref_viewimages";

    private SharedPreferences settings;

    private OnSharedPreferenceChangeListener listener;
    private File file;
    private static  final String FILENAME = "jasondata";

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

        settings = PreferenceManager.getDefaultSharedPreferences(this);

        listener = new OnSharedPreferenceChangeListener() {

            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                                                  String key) {
                MainActivity.this.refreshDisplay(null);
            }
        };
        settings.registerOnSharedPreferenceChangeListener(listener);

        File extDir = getExternalFilesDir(null);
        String path = extDir.getAbsolutePath();
        UIHelper.displayText(this, R.id.textView, path);

        file = new File(extDir,FILENAME);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    public void setPreference(View v) {
        Log.i(LOGTAG, "Clicked set");
        Intent intent = new Intent(this, UIHelper.class);
        startActivity(intent);
    }

    public void refreshDisplay(View v) {
        Log.i(LOGTAG, "Clicked show");

        String prefValue = settings.getString(USERNAME, "Not found");
        UIHelper.displayText(this, R.id.textView, prefValue);

    }

    public void createFile(View v) throws IOException, JSONException {

        if(!checkExternalStorage())
        {
            return;
        }

        JSONArray data = getNewJSONData();

        String text = data.toString();

        try{
            FileOutputStream fos = new FileOutputStream("tours");
            fos.write(text.getBytes());
            fos.close();

            UIHelper.displayText(this, R.id.textView, "File written to disk:\n" + data.toString());
        }
        catch (IOException e) {
            e.printStackTrace();
            UIHelper.displayText(this, R.id.textView, e.toString());
        }

    }

    public void readFile(View v) throws IOException, JSONException {

        FileInputStream fis = new FileInputStream("tours");
        BufferedInputStream bis = new BufferedInputStream(fis);
        StringBuffer b = new StringBuffer();
        while (bis.available() != 0) {
            char c = (char) bis.read();
            b.append(c);
        }
        bis.close();
        fis.close();

        JSONArray data = new JSONArray(b.toString());

        StringBuffer toursBuffer = new StringBuffer();
        for (int i = 0; i < data.length(); i++) {
            String tour = data.getJSONObject(i).getString("tours");
            toursBuffer.append(tour + "\n");
        }

        UIHelper.displayText(this, R.id.textView, toursBuffer.toString());
    }

    private JSONArray getNewJSONData() throws JSONException {
        JSONArray data = new JSONArray();
        JSONObject tour;

        tour = new JSONObject();
        tour.put("tour", "Salton Sea");
        tour.put("price", 900);
        data.put(tour);

        tour = new JSONObject();
        tour.put("tour", "Death Valley");
        tour.put("price", 600);
        data.put(tour);

        tour = new JSONObject();
        tour.put("tour", "San Francisco");
        tour.put("price", 1200);
        data.put(tour);
        return data;
    }

    public boolean checkExternalStorage()
    {
        String state = Environment.getExternalStorageState();
        if (state.equals(Environment.MEDIA_MOUNTED))
        {
            return true;
        }
        else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
        {
            UIHelper.displayText(this, R.id.textView,"read-only");
        }
        else
        {
            UIHelper.displayText(this, R.id.textView,"unavailable");
        }
        return false;
    }

Main Activity XML

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/editText"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true" />

<Button
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Create File"
    android:id="@+id/createFile"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginBottom="92dp"
    android:onClick="createFile"/>

<Button
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Read File"
    android:id="@+id/readFile"
    android:layout_alignTop="@+id/createFile"
    android:layout_centerHorizontal="true"
    android:onClick="readFile"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Command"
    android:textSize="10sp"
    android:id="@+id/textView"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/readFile"
    android:layout_alignRight="@+id/editText"
    android:layout_alignEnd="@+id/editText" />

UIHelper Java class package claudiu.externalstorage;

import android.app.Activity;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;

public class UIHelper {

    public static void displayText(Activity activity, int id, String text) {
        TextView tv = (TextView) activity.findViewById(id);
        tv.setText(text);
    }

    public static String getText(Activity activity, int id) {
        EditText et = (EditText) activity.findViewById(id);
        return et.getText().toString();
    }

    public static boolean getCBChecked(Activity activity, int id) {
        CheckBox cb = (CheckBox) activity.findViewById(id);
        return cb.isChecked();
    }

    public static void setCBChecked(Activity activity, int id, boolean value) {
        CheckBox cb = (CheckBox) activity.findViewById(id);
        cb.setChecked(value);
    }

Manifest

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

    <application

        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Logcat trace

 9318-9318/? W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:409)
   9318-9318/? W/System.err﹕ java.io.FileNotFoundException: /tours: open failed: EROFS (Read-only file system)
   9318-9318/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
   9318-9318/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
   9318-9318/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
   9318-9318/? W/System.err﹕ at claudiu.externalstorage.MainActivity.createFile(MainActivity.java:93)
   9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
   9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515)
   9318-9318/? W/System.err﹕ at android.view.View$1.onClick(View.java:3991)
   9318-9318/? W/System.err﹕ at android.view.View.performClick(View.java:4748)
   9318-9318/? W/System.err﹕ at android.view.View$PerformClick.run(View.java:19535)
   9318-9318/? W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:733)
   9318-9318/? W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:95)
   9318-9318/? W/System.err﹕ at android.os.Looper.loop(Looper.java:146)
   9318-9318/? W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5679)
   9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
   9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515)
   9318-9318/? W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
   9318-9318/? W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
   9318-9318/? W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
   9318-9318/? W/System.err﹕ Caused by: libcore.io.ErrnoException: open failed: EROFS (Read-only file system)
   9318-9318/? W/System.err﹕ at libcore.io.Posix.open(Native Method)
   9318-9318/? W/System.err﹕ at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
   9318-9318/? W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:393)
   9318-9318/? W/System.err﹕ ... 18 more

Answer

CommonsWare picture CommonsWare · May 23, 2015
FileOutputStream fos = new FileOutputStream("tours");

This is not pointing anywhere that you can read or write. Always use a method to get at the base locations where you can read and write.

If you are looking to write to internal storage, change this to be something like:

FileOutputStream fos = new FileOutputStream(new File(getFilesDir(), "tours"));

If you are looking to write to external storage, change this to be something like:

FileOutputStream fos = new FileOutputStream(new File(getExternalFilesDir(null), "tours"));