0

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
    }
}
Dewald Swanepoel
  • 1,651
  • 4
  • 15
  • 38
  • `// Do whartever` - you should check to see if you actually have an exception. Doing nothing is not good. – Simon Sep 08 '13 at 14:03
  • u might be getting some exceptions in the middle while writing....try catching the exception in "catch block" – ASP Sep 08 '13 at 14:12
  • I'm not getting any exceptions. I didn't think that including all of my code that deals with exceptions were germane to this question. Rest assured, I don't have an empty catch block. – Dewald Swanepoel Sep 08 '13 at 14:18

3 Answers3

1

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

Jason
  • 231
  • 3
  • 14
  • Thanks, this works. I do find it extremely frustrating though that, by all accounts, my code is fine, only it doesn't work. If it's not fine, I'd like to know at least why it isn't. But thanks for your solution. – Dewald Swanepoel Sep 08 '13 at 15:00
  • i will try your code with debug and see how OutputStreamWriter() works – Jason Sep 08 '13 at 15:24
  • 1
    hi! sorry for comment so late but on the same snippet (mine) yo can append just changing two things; 1: new BufferedWriter(new FileWriter(outputFile)); for new BufferedWriter(new FileWriter(outputFile,true)); that "true" means to append. and 2: mwriter.write(data); //DATA WRITE TO FILE to writer.append(data); and now you can append and do a log for example – Jason Oct 06 '13 at 00:01
1

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

  • jboi
    • 11,324
    • 4
    • 36
    • 43
    0

    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();
                }
                }
              }
            } 
    
    Ritesh Gune
    • 16,629
    • 6
    • 44
    • 72
    • So what exactly does Context.MODE_PRIVATE mean then? Anyway, it doesn't work. If I change the mode to Context.MODE_APPEND, exactly the same thing happens. File is created, but contents are empty. – Dewald Swanepoel Sep 08 '13 at 14:23