【问题标题】:file saving(object) to android文件保存(对象)到android
【发布时间】:2013-08-09 17:30:46
【问题描述】:

以下是我发现的 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);

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

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

(我是初中生,所以,我知道的很少,请尽量少用)

【问题讨论】:

    标签: android input


    【解决方案1】:

    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>
    

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

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

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

    【讨论】:

    • 这是整个代码吗?我不知道要修改什么,请告诉我更多信息。
    • @user2666729 我编辑了我的帖子,你现在应该实现它,如果没有,我建议你阅读“基本序列化”的教程。
    • 在deserializeObject中,其返回错误不能对非静态方法进行静态引用。另外,我将如何用你告诉我的方法反序列化一个字节数组? (deserializeObject 中没有参数了)
    • @user2666729 试试 Edit2。
    • 这会返回很多错误。假设我有一个对象 fl,其中 int a 作为数据成员。我该怎么写呢?
    【解决方案2】:

    我在一个项目中遇到了同样的问题,我们最终使用了 SQLite 数据库。如果你想要持久化,现在真的没有其他选择(DB4O等都行不通)...

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

    您确实必须为数据库解决方案(检索和插入对象)重构代码,但遗憾的是,没有真正的替代方案(不要使用诸如存储 csv 文件或类似方法之类的肮脏方式...)

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

    【讨论】:

    • 当问题是将 5-10 个变量保存为 Configuration 时,我真的不认为有必要使用 SQLite,并且通过序列化编写文件比 SQLite 更容易,应该使用最适合(就良好的实现性能清洁方式而言)需求恕我直言。
    • 好的,我编辑了。对于 5-10 个变量,我建议使用 SharedPreferences。
    • 是的,SharedPreferences 只存储原语,所以如果你想保持对象本身的结构而不是键值对,序列化仍然是一种方式。
    • 我正在关注这个(我在 android 上和作为一个简单的 java 应用程序都试过这个)但是我的“data.bin”文件没有被创建。告诉我哪里错了?
    猜你喜欢
    • 2011-04-07
    • 1970-01-01
    • 2012-03-27
    • 2016-04-21
    • 1970-01-01
    • 2016-08-15
    • 2013-12-27
    • 2020-11-03
    • 1970-01-01
    相关资源
    最近更新 更多