文件保存(对象)到android

时间:2013-08-09 17:30:46

标签: android input

下面是我找到的4个功能(经过激烈的谷歌搜索) (我的目标是能够编写我创建的对象的实例,然后再检索它们)

public static Object deserializeObject(byte[] bytes)
{
    // TODO: later read Region object saved in file named by the time stamp during
    // saving.
    // ObjectInputStream inputStream = new ObjectInputStream(new
    // FileInputStream(fileName));

    try {
        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
        Object object = in.readObject();
        in.close();

        return object;
      } catch(ClassNotFoundException cnfe) {
        Log.e("deserializeObject", "class not found error", cnfe);

        return null;
      } catch(IOException ioe) {
        Log.e("deserializeObject", "io error", ioe);

        return null;
      }
}


/**
 * Writes content to internal storage making the content private to 
 * the application. The method can be easily changed to take the MODE 
 * as argument and let the caller dictate the visibility: 
 * MODE_PRIVATE, MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE, etc.
 * 
 * @param filename - the name of the file to create
 * @param content - the content to write
 */
public void writeInternalStoragePrivate(
        String filename, byte[] content) {
    try {
        //MODE_PRIVATE creates/replaces a file and makes 
        //  it private to your application. Other modes:
        //    MODE_WORLD_WRITEABLE
        //    MODE_WORLD_READABLE
        //    MODE_APPEND
        FileOutputStream fos = 
           openFileOutput(filename, Context.MODE_PRIVATE);
        fos.write(content);
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}



/**
 * Reads a file from internal storage
 * @param filename the file to read from
 * @return the file content
 */
public byte[] readInternalStoragePrivate(String filename) {
    int len = 1024;
    byte[] buffer = new byte[len];
    try {
        FileInputStream fis = openFileInput(filename);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int nrb = fis.read(buffer, 0, len); // read up to len bytes
        while (nrb != -1) {
            baos.write(buffer, 0, nrb);
            nrb = fis.read(buffer, 0, len);
        }
        buffer = baos.toByteArray();
        fis.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return buffer;
}

我正在使用它来尝试读取对象 q1.a = 12;

      byte []q=serializeObject(q1); 
      writeInternalStoragePrivate("shared",q);


byte []w=readInternalStoragePrivate("shared"); 
      fl y=(fl) deserializeObject(w);

(前两行是序列化和写入,另外两行是读取和反序列化。)

但是,每次关闭应用程序时,数据都会丢失,并重置为0.

(我是一名中学生,所以,我知道的非常少,请尽量保留)

2 个答案:

答案 0 :(得分:2)

Writeread上你需要将FileOutput / InputStream包装到ObjectOutput / InputStream,你在代码之上调用readObject()但是你从不调用writeObject()所以Serialization process一开始就没有完成。

编辑3:我决定删除所有尝试的代码,让你意识到如何做到这一点并放一些复制/粘贴工作代码,你还需要学习这段代码(不使用对流或良好实践,这是作业对你而言):

1-创建一个新的清洁项目。

2-将此添加到您的MainActivity:

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.w("asd","saasd");

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public void save(View view){
    writer.execute();
}

public void read(View view){
    reader.execute();
}

private  AsyncTask writer = new AsyncTask(){

  @Override
  protected Object doInBackground(Object[] objects) {
      writeConfigurationFile(new MyNumber(5));
      return null;
  }
};

private AsyncTask reader = new AsyncTask(){
    MyNumber number;
    @Override
    protected Object doInBackground(Object... objects) {
       number = readConfigurationFile();
        return null;
    }

    @Override
    protected void onPostExecute(Object object) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TextView t = (TextView)findViewById(R.id.number_info);
                t.setText(String.valueOf(number.getA()));
            }
        });

    }
};


private void writeConfigurationFile(MyNumber number) {
    FileOutputStream fos;
    try {
        fos = openFileOutput("MyNumberFile", Context.MODE_PRIVATE);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(number);
        oos.close();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.w("LOG:", e.getMessage());

    } catch (IOException e) {
        Log.w("LOG:", e.getMessage());

    }
}

private MyNumber readConfigurationFile() {
    FileInputStream fis;
   MyNumber number = null;
    try {
        fis = openFileInput("MyNumberFile");
        ObjectInputStream ois = new ObjectInputStream(fis);
        number = (MyNumber) ois.readObject();
        ois.close();
        fis.close();
    } catch (FileNotFoundException e) {
        Log.w("LOG:", e.getMessage());

    } catch (IOException e) {
        Log.w("LOG:", e.getMessage());

    } catch (ClassNotFoundException e) {
        Log.w("LOG:", e.getMessage());

    }
    return number;
}

}

3-在MainActivity所在的同一个包中创建一个名为MyNumber的新类,并将其添加到MyNumber.java文件中:

import java.io.Serializable;

/**
* Created by joseph on 09/08/13.
*/
public class MyNumber implements Serializable {
int a;

public MyNumber(int a) {
    this.a = a;
}

public int getA() {
    return a;
}

public void setA(int a) {
    this.a = a;
}
}

并持续activity_main.xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save"
        android:id="@+id/save"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:onClick="save"/>

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Read"
        android:id="@+id/read"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="17dp"
        android:onClick="read"/>

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Number From File"
        android:id="@+id/number_info"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        />
</RelativeLayout>

将此添加到Application标记上方的AndroidManifest.xml中:

<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />

然后运行程序,当你单击save button创建一个值为5的int的新MyNumber对象并进行序列化时,单击read button我们读取文件并设置int的编号在此之后的textView中,您可以关闭应用程序并再次打开它并单击读取并显示保存在文件中的数字(因为文件仍附加到应用程序数据),如果您不理解或未实现这个代码你想要什么我真的很抱歉,因为这不是一个你的家庭作业将要完成的网页,不要再指望这一点,我只是想帮助你,但是这样的代码我'我根本无法帮助你学习。

答案 1 :(得分:0)

我在项目中遇到了同样的问题,最后我们使用了SQLite数据库。如果你想要持久性,那么现在就没有其他选择(DB4O等都不起作用)......

查看http://sqlite.com/ SQLite有很多教程!

你真的必须重新构建数据库解决方案的代码(检索和插入对象)但遗憾的是,没有真正的替代方法(不要使用诸如存储csv文件或类似方法的脏方法......)< / p>

编辑:好的,如果您只想存储5个变量,可以使用SharedPreferences。