安卓 FileInputStream 读取 txt 文件并转换为字符串

29

有没有专家能够帮助我?在我的Android主活动中,我尝试将一个字符串保存到文件中,如果用户之前设置过它,则检索它。我没有找到任何与我所做的接近的示例。如果能得到任何帮助,我将不胜感激!这是导致崩溃的我的测试用例:

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

为什么使用文件呢?尝试使用SharedPreferences - 代码量更少,更整洁。 - Jens
3个回答

63

尝试使用以下代码来读取文件:

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

2
请帮我一下,第二行显示错误openFileInput未定义...该怎么办? - someone_ smiley
9
这个对吗?在创建字符串之前,难道不需要考虑读取的字节数吗?类似这样:while ((n = fis.read(buffer)) != -1) { fileContent.append(new String(buffer, 0, n)); } - Pin
你是正确的 Pin。 如果你有超过缓冲区大小(1024)的内容,旧的多余数据将被写入 fileContent 缓冲区。 - disco
3
这段代码中还有一个bug。你每次读取1024个字节,并假定它们可以使用默认字符集转换为字符串,但是安卓系统上的默认字符集是UTF8,这是一种可变长度编码。如果文件的第1024个字节恰好是一个2字节字符(或3字节字符的第1或2个字节等),那么它将被替换为指示编码错误的标记字符,并且接下来的字符也会受到损坏。为避免此类错误,请在读取文本时使用Reader而不是InputStream - Jules
当我运行它时,它使我的应用程序崩溃了。 - Si8
显示剩余4条评论

38

可以尝试这样做

    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() ;
    }

我认为这是比其他答案更好的解决方案。如果有一个非常大的文件,你无法将整个文件读入内存,那么你可以改变while循环,逐行处理它。另一种解决方案不像这个那么容易修改。 - rml
可能会缺少 datax.append (System.lineSeparator ()); 吗?另外, StringBuilderStringBuffer 更有效率 - 除此之外:感谢您的帮助。 - Martin

2
少即是多;
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
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接