29

Any experts available to help me? In my Android main activity, I'm trying to save a String to a file and then retrieve it if the user has set it before. Wasn't able to find any examples close to what I am doing. I would most appreciate any help! Here is my test case that crashes:

String testString = "WORKS";
String readString;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    FileOutputStream fos;

    try {
        fos = openFileOutput("test.txt", Context.MODE_PRIVATE);
        fos.write(testString.getBytes());
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();

    } catch (IOException e) {
        e.printStackTrace();

    }

    File file = getBaseContext().getFileStreamPath("test.txt");

    if (file.exists()) {

        FileInputStream fis;

        try {
            fis = openFileInput("test.txt");
            fis.read(readString.getBytes());
            fis.close();

        } catch (IOException e) {
            e.printStackTrace();

        } 

        txtDate.setText(String.valueOf(readString));

       } else {
                     // more code
       }
     }
 }
jbearden
  • 1,839
  • 2
  • 19
  • 23
  • Why use a File? Try using [SharedPreferences](http://developer.android.com/reference/android/content/SharedPreferences.html) - lot less code and mess. – Jens Feb 01 '12 at 12:16

3 Answers3

62

For reading file try this:

FileInputStream fis;
fis = openFileInput("test.txt");
StringBuffer fileContent = new StringBuffer("");

byte[] buffer = new byte[1024];

while ((n = fis.read(buffer)) != -1) 
{ 
  fileContent.append(new String(buffer, 0, n)); 
}
user370305
  • 103,719
  • 23
  • 157
  • 149
  • 2
    Please help me a little, second line show error openFileInput is undefined... what to do? – someone_ smiley Sep 19 '12 at 04:53
  • @someone_smiley - Where are you writing this code line? It is method of Activity. So either put your code in Activity or use Context of Activity with this method.. – user370305 Sep 19 '12 at 05:11
  • hi @user370305 - my code isn't in any activity. its just a class that i intended to design to ease some task. i will send file path as parameter from a class(again not an activity) to it and let method do the rest. please advice how can i achieve this. thanks for your time – someone_ smiley Sep 19 '12 at 08:42
  • @someone_smiley - Pass context(reference) of your Activity to that class and in that using that activity's context access the method.. something like, `context.openFileInput();` – user370305 Sep 19 '12 at 08:48
  • @user370305 - Thanks for all your help. i try put method in activity and its work. and i also try pass data input stream to that function and thats also work well. – someone_ smiley Sep 24 '12 at 03:19
  • 9
    Is this correct? Don't you have to take into account the number of bytes read before creating the string? Something like this: while ((n = fis.read(buffer)) != -1) { fileContent.append(new String(buffer, 0, n)); } – Pin Mar 13 '13 at 15:49
  • You are correct Pin. In case you have content which exceeds the buffer size (1024) the old excess data will be written to the fileContent buffer. – disco May 02 '13 at 08:33
  • 3
    (Copying my comment from an answer that copied this code...) There's another bug in this code. You're reading 1024 bytes at a time and assuming they can be converted to a string using the default charset, but the default charset on Android is UTF8, which is a variable-length encoding. If the 1024th byte of a file is the start of a 2-byte character (or the 1st or 2nd byte of a 3-byte character, or so on) it will be replaced with a marker character that indicates an encoding error, and the next will be corrupted. Use a `Reader` when reading text, not an `InputStream`, to avoid errors like this. – Jules Aug 01 '13 at 15:35
  • It FC my app when I ran it – Si8 Aug 04 '13 at 23:25
36

Try something like this

    public void writeData ( String data ) {
        try {
            FileOutputStream fOut = openFileOutput ( "settings.dat" , MODE_WORLD_READABLE ) ;
            OutputStreamWriter osw = new OutputStreamWriter ( fOut ) ;
            osw.write ( data ) ;
            osw.flush ( ) ;
            osw.close ( ) ;
        } catch ( Exception e ) {
            e.printStackTrace ( ) ;
        }
    }

    public String readSavedData ( ) {
        StringBuffer datax = new StringBuffer("");
        try {
            FileInputStream fIn = openFileInput ( "settings.dat" ) ;
            InputStreamReader isr = new InputStreamReader ( fIn ) ;
            BufferedReader buffreader = new BufferedReader ( isr ) ;

            String readString = buffreader.readLine ( ) ;
            while ( readString != null ) {
                datax.append(readString);
                readString = buffreader.readLine ( ) ;
            }

            isr.close ( ) ;
        } catch ( IOException ioe ) {
            ioe.printStackTrace ( ) ;
        }
        return datax.toString() ;
    }
Arslan Anwar
  • 18,486
  • 18
  • 74
  • 104
  • I think this is a better solution then the other answer. If there is a very big file there and you can not read the whole file to memory, then you can change the while to handle it one line after another. The other solution is not as easy to change as this one. – rml Jun 21 '13 at 22:00
  • Could it be that there is a `datax.append (System.lineSeparator ());` missing? And `StringBuilder` is more efficient then `StringBuffer` — apart from that: Thanks, great help. – Martin Jan 11 '15 at 18:49
2

Less is more;

public class MainActivity extends AppCompatActivity {

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

        TextView tvText = (TextView) findViewById(R.id.tvText);

        try {
            // Create File and Content
            String FILE_NAME = "hallo.txt";
            String content = "Hallo Welt!";

            FileOutputStream fos = openFileOutput(FILE_NAME, MODE_PRIVATE);
            fos.write(content.getBytes());
            fos.close();

            // Read File and Content
            FileInputStream fin = openFileInput(FILE_NAME);
            int size;
            String neuText = null;

            // read inside if it is not null (-1 means empty)
            while ((size = fin.read()) != -1) {
                // add & append content
                neuText += Character.toString((char) size);
            }
            // Set text to TextView
            tvText.setText(neuText);

        } catch (Exception error) {
            // Exception
        }
    }
}
Umut D.
  • 1,557
  • 20
  • 22