Dewald Swanepoel
Dewald Swanepoel

Reputation: 1681

I can create file but can't write to it

Could someone look at this snippet of code please and let me know what I'm doing wrong? It's a simple function that takes a string as parameter which it uses as a file name, adding ".txt" to the end of it.

The function checks if the file exists, creating it if it doesn't and then writes two lines of text to the file. Everything appears to be working and the file is created successfully on the sd card. However, after everything is done, the file is empty (and has a size of 0 bytes).

I suspect it's something obvious that I'm overlooking.

public void writeFile(String fileName) {
    String myPath = new File(Environment.getExternalStorageDirectory(), "SubFolderName");
    myPath.mkdirs();

    File file = new File(myPath, fileName+".txt");

    try {
        if (!file.exists()) {
            if (!file.createNewFile()) {
                Toast.makeText(this, "Error Creating File", Toast.LENGTH_LONG).show();
                return;
            }
        }

        OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_PRIVATE));
        writer.append("First line").append('\n');
        writer.append("Second line").append('\n');

        writer.close();
    }
    catch (IOException e) {
        // Do whatever
    }
}

Upvotes: 0

Views: 2105

Answers (3)

jboi
jboi

Reputation: 11892

That one took a while to find out. The javadocs here brought me on the right track. It says:

Parameters
  • name The name of the file to open; can not contain path separators.
  • mode Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_APPEND to append to an existing file, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.
  • The file is created, if it does not exist, but it is created in the private app space. You create the file somewhere on the sd card using File.createNewFile() but when you do context.openFileOutput() it creates always a private file in the private App space.

    EDIT: Here's my code. I've expanded your method by writing and reading the lines and print what I got to logcat.

    <pre>
        public void writeFile(String fileName) {
        try {
            OutputStreamWriter writer = new OutputStreamWriter(
                    getContext().openFileOutput(fileName + ".txt", Context.MODE_PRIVATE));
            writer.append("First line").append('\n');
            writer.append("Second line").append('\n');
    
            writer.close();
        }
        catch (IOException e) {
            Log.e("STACKOVERFLOW", e.getMessage(), e);
            return;
            // Do whatever
        }
    
        // Now read the file
        try {
            BufferedReader is = new BufferedReader(
                    new InputStreamReader(
                            getContext().openFileInput(fileName + ".txt")));
            for(String line = is.readLine(); line != null; line = is.readLine())
                Log.d("STACKOVERFLOW", line);
    
            is.close();
        } catch (IOException e) {
            Log.e("STACKOVERFLOW", e.getMessage(), e);
            return;
            // Do whatever
        }
    }
    

    Upvotes: 1

    Ritesh Gune
    Ritesh Gune

    Reputation: 16729

    Change the mode from Context.MODE_PRIVATE to Context.MODE_APPEND in openFileOutput()

    MODE_APPEND

    MODE_PRIVATE

    Instead of

    OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_PRIVATE));
    

    Use

    OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_APPEND));
    

    UPDATE :

    1.

    FileOutputStream osr = new FileOutputStream(file.getName(), true); // this will set append flag to true
    
    OutputStreamWriter writer = new OutputStreamWriter(osr);
    BufferedWriter fbw = new BufferedWriter(writer);
                fbw.write("First line");
                fbw.newLine();
                fbw.write("Second line");
                fbw.newLine();
                fbw.close();
    

    Or 2.

    private void writeFileToInternalStorage() {
              FileOutputStream osr = new FileOutputStream(file.getName(), true); // this will set append flag to true
              String eol = System.getProperty("line.separator");
              BufferedWriter fbw = null;
              try {
                  OutputStreamWriter writer = new OutputStreamWriter(osr);
                  fbw = new BufferedWriter(writer);
                  fbw.write("First line" + eol);
                  fbw.write("Second line" + eol);           
    
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                if (fbw != null) {
                try {
                    fbw.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
                }
              }
            } 
    

    Upvotes: 0

    Jason
    Jason

    Reputation: 231

    Hi I will show you the full code I use, works perfect. I don't use

     new OutputStreamWriter() 
    

    i use

    new BufferedWriter()
    

    here is my Snippet

    public void writeToFile(Context context, String fileName, String data) {
    
        Writer mwriter;
    
        File root = Environment.getExternalStorageDirectory();
        File dir = new File(root.getAbsolutePath() + File.separator + "myFolder");
    
        if (!dir.isDirectory()) {
            dir.mkdir();
        }
    
        try {
            if (!dir.isDirectory()) {
                throw new IOException(
                    "Unable to create directory myFolder. SD card mounted?");
            }
            File outputFile = new File(dir, fileName);
            mwriter = new BufferedWriter(new FileWriter(outputFile));
            mwriter.write(data); // DATA WRITE TO FILE
            Toast.makeText(context.getApplicationContext(),
                "successfully saved to: " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
            mwriter.close();
        } catch (IOException e) {
            Log.w("write log", e.getMessage(), e);
            Toast.makeText(context, e.getMessage() + " Unable to write to external storage.",Toast.LENGTH_LONG).show();
            }
    }
    

    -- Original Code --

    Upvotes: 1

    Related Questions