在Android上将ArrayList保存到文件

11
我有一个字符串类型的ArrayList,其中的字符串是由用户填充的,我想在另一个活动中使用ListView来查看他们保存的字符串,并将用户填充的ArrayList保存下来,但我不知道如何实现。我已经尝试使用FileOutputStream、SharedPreferences,并查看了许多示例。
例如,我有:
ArrayList<String> give = new ArrayList<String>();

为了保存ArrayList,我尝试过以下方法:

FileOutputStream fos = openFileOutput(MYFILENAME, Context.MODE_PRIVATE);
fos.write(give.getBytes());
fos.close();

但这完全不起作用


你尝试过将数组序列化并写入文件吗?我做过这个。你用的是哪个版本的安卓系统?最新版本现在有保存数组到首选项的方法。 - JPM
较新的Android版本,例如2.3.6。听起来很有趣,我还没有听说过这个。 - NightSkyCode
所以下面的答案对你没有用...将ArrayList保存到SharedPreferences中,因为它是针对3.0版本发布的。如果你需要一个可序列化的类,请告诉我,我有一个适用于这种情况。 - JPM
2个回答

22

这里是一段代码,可以将可序列化对象写入文件,这可能是你需要的。我已经使用ArrayList进行了测试,它可以正常工作。您也可以修改输出,而不是将其写入文件,可以通过extras或bundle将其传递给活动。我在Android版本<3.0中使用了此方法。

要读取已包含序列化对象的文件:

String ser = SerializeObject.ReadSettings(act, "myobject.dat");
if (ser != null && !ser.equalsIgnoreCase("")) {
    Object obj = SerializeObject.stringToObject(ser);
    // Then cast it to your object and 
    if (obj instanceof ArrayList) {
        // Do something
        give = (ArrayList<String>)obj;
    }
}

要将对象写入文件,请使用:

String ser = SerializeObject.objectToString(give);
if (ser != null && !ser.equalsIgnoreCase("")) {
    SerializeObject.WriteSettings(act, ser, "myobject.dat");
} else {
    SerializeObject.WriteSettings(act, "", "myobject.dat");
}

用于序列化对象的类:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;

import android.content.Context;
import android.util.Base64InputStream;
import android.util.Base64OutputStream;
import android.util.Log;

/**
 * Take an object and serialize and then save it to preferences
 * @author John Matthews
 *
 */
public class SerializeObject {
    private final static String TAG = "SerializeObject";

    /**
     * Create a String from the Object using Base64 encoding
     * @param object - any Object that is Serializable
     * @return - Base64 encoded string.
     */
    public static String objectToString(Serializable object) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            new ObjectOutputStream(out).writeObject(object);
            byte[] data = out.toByteArray();
            out.close();

            out = new ByteArrayOutputStream();
            Base64OutputStream b64 = new Base64OutputStream(out,0);
            b64.write(data);
            b64.close();
            out.close();

            return new String(out.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Creates a generic object that needs to be cast to its proper object
     * from a Base64 ecoded string.
     * 
     * @param encodedObject
     * @return
     */
    public static Object stringToObject(String encodedObject) {
        try {
            return new ObjectInputStream(new Base64InputStream(
                    new ByteArrayInputStream(encodedObject.getBytes()), 0)).readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Save serialized settings to a file
     * @param context
     * @param data
     */
    public static void WriteSettings(Context context, String data, String filename){ 
        FileOutputStream fOut = null; 
        OutputStreamWriter osw = null;

        try{
            fOut = context.openFileOutput(filename, Context.MODE_PRIVATE);       
            osw = new OutputStreamWriter(fOut); 
            osw.write(data); 
            osw.flush(); 
            //Toast.makeText(context, "Settings saved",Toast.LENGTH_SHORT).show();
        } catch (Exception e) {       
            e.printStackTrace(); 
           // Toast.makeText(context, "Settings not saved",Toast.LENGTH_SHORT).show();
        } 
        finally { 
            try { 
                if(osw!=null)
                    osw.close();
                if (fOut != null)
                    fOut.close(); 
            } catch (IOException e) { 
                   e.printStackTrace(); 
            } 
        } 
    }

    /**
     * Read data from file and put it into a string
     * @param context
     * @param filename - fully qualified string name
     * @return
     */
    public static String ReadSettings(Context context, String filename){ 
        StringBuffer dataBuffer = new StringBuffer();
        try{
            // open the file for reading
            InputStream instream = context.openFileInput(filename);
            // if file the available for reading
            if (instream != null) {
                // prepare the file for reading
                InputStreamReader inputreader = new InputStreamReader(instream);
                BufferedReader buffreader = new BufferedReader(inputreader);

                String newLine;
                // read every line of the file into the line-variable, on line at the time
                while (( newLine = buffreader.readLine()) != null) {
                    // do something with the settings from the file
                    dataBuffer.append(newLine);
                }
                // close the file again
                instream.close();
            }

        } catch (java.io.FileNotFoundException f) {
            // do something if the myfilename.txt does not exits
            Log.e(TAG, "FileNot Found in ReadSettings filename = " + filename);
            try {
                context.openFileOutput(filename, Context.MODE_PRIVATE);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            Log.e(TAG, "IO Error in ReadSettings filename = " + filename);
        }

        return dataBuffer.toString();
    }

}

抱歉,忘记为此添加导入 import android.util.Base64InputStream; import android.util.Base64OutputStream; - JPM
1
哦!我把构建目标设置得太低了。我已经修复了。你的答案对我非常有帮助!非常感谢! - NightSkyCode
我认为这个解决方案并不可靠,因为在.readObject()行经常会出现异常。 这个解决方案要干净得多,我没有遇到任何问题(除了明显更慢):https://dev59.com/JmQo5IYBdhLWcg3wXeb5#16111797 - ban-geoengineering

5

1
他们将其保存到哈希集合中以进行对象操作,并将其转换回列表。似乎不必这样做。 - NightSkyCode
我同意这不是保存对象最有效的方式。 - JPM

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