मैं किसी ऑब्जेक्ट को कैसे अनुक्रमित करूं और उसे एंड्रॉइड में फ़ाइल में सहेजूं?


128

कहो कि मेरे पास कुछ सरल वर्ग है और एक बार इसे एक ऐसी वस्तु के रूप में तैयार कर दिया जाता है जिसे मैं किसी फ़ाइल में इसकी सामग्री को क्रमबद्ध करने में सक्षम होना चाहता हूं, और बाद में उस फ़ाइल को लोड करके इसे पुनः प्राप्त कर सकता हूं ... मुझे यकीन नहीं है कि यहां कहां शुरू करना है; किसी फ़ाइल में इस ऑब्जेक्ट को क्रमांकित करने के लिए मुझे क्या करने की आवश्यकता है?

public class SimpleClass {
   public string name;
   public int id;
   public void save() {
       /* wtf do I do here? */
   }
   public static SimpleClass load(String file) {
       /* what about here? */
   }
}

यह शायद दुनिया का सबसे आसान सवाल है, क्योंकि यह .NET में एक बहुत ही सरल काम है, लेकिन एंड्रॉइड में मैं बहुत नया हूं इसलिए मैं पूरी तरह से खो गया हूं।

जवाबों:


250

बचत (w / o अपवाद हैंडलिंग कोड):

FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();
fos.close();

लोड हो रहा है (w / o अपवाद हैंडलिंग कोड):

FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
SimpleClass simpleClass = (SimpleClass) is.readObject();
is.close();
fis.close();

बहुत उपयोगी। क्या आप बता सकते हैं कि क्या हमें ऑब्जेक्ट फाइल के रूप में लिखने के लिए क्लास को क्रमबद्ध करना है।
अरुण चेट्टूर

4
यदि आप Serializable इंटरफ़ेस का उपयोग करते हैं तो यह कार्यक्षमता आपके वर्ग में अंतर्निहित है। यदि आप चाहते हैं कि सभी सरल वस्तु क्रमांकन है, तो मैं इसका उपयोग करूंगा। इसे लागू करना भी बेहद आसान है। developer.android.com/reference/java/io/Serializable.html
mtmurdock

6
+1, कई वस्तुओं को बचाने के लिए ट्रिक की आवश्यकता होती है: stackoverflow.com/a/1195078/1321401
लुटेन

2
क्या fos.close () और fis.close () के लिए भी कॉल होनी चाहिए?
इडेडांटे

मैं पेपर की सलाह दूंगा । यह Kryo क्रमांकन और बहुत तेजी से सामान्य जावा क्रमांकन का उपयोग करता है।
अलेक्सी मैसी

36

मैंने यह 2 विकल्प (पढ़ने / लिखने) की कोशिश की है, सादे वस्तुओं के साथ, वस्तुओं की सरणी (150 ऑब्जेक्ट), मैप:

विकल्प 1:

FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();

विकल्प 2:

SharedPreferences mPrefs=app.getSharedPreferences(app.getApplicationInfo().name, Context.MODE_PRIVATE);
SharedPreferences.Editor ed=mPrefs.edit();
Gson gson = new Gson(); 
ed.putString("myObjectKey", gson.toJson(objectToSave));
ed.commit();

विकल्प 2 विकल्प 1 की तुलना में दोगुना तेज है

विकल्प 2 असुविधा यह है कि आपको पढ़ने के लिए विशिष्ट कोड बनाना होगा:

Gson gson = new Gson();
JsonParser parser=new JsonParser();
//object arr example
JsonArray arr=parser.parse(mPrefs.getString("myArrKey", null)).getAsJsonArray();
events=new Event[arr.size()];
int i=0;
for (JsonElement jsonElement : arr)
    events[i++]=gson.fromJson(jsonElement, Event.class);
//Object example
pagination=gson.fromJson(parser.parse(jsonPagination).getAsJsonObject(), Pagination.class);

3
आप क्यों कहेंगे विकल्प 2 तेज है? शायद इसलिए कि SharedPreferences को स्मृति में रखा जाता है और आपके द्वारा मापा गया समय इसे फ़ाइल सिस्टम में सहेजना शामिल नहीं करता है? मैं यह पूछता हूं क्योंकि मुझे लगता है कि एक वस्तु धारा के लिए क्रमबद्ध करना एक JSON स्ट्रिंग की तुलना में अधिक कुशल होना चाहिए।
CesarPim

10

मैंने सिर्फ जेनरिक के साथ इसे संभालने के लिए एक वर्ग बनाया है, इसलिए इसका उपयोग उन सभी प्रकार के प्रकारों के साथ किया जा सकता है जो क्रमबद्ध हैं:

public class SerializableManager {

    /**
     * Saves a serializable object.
     *
     * @param context The application context.
     * @param objectToSave The object to save.
     * @param fileName The name of the file.
     * @param <T> The type of the object.
     */

    public static <T extends Serializable> void saveSerializable(Context context, T objectToSave, String fileName) {
        try {
            FileOutputStream fileOutputStream = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

            objectOutputStream.writeObject(objectToSave);

            objectOutputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Loads a serializable object.
     *
     * @param context The application context.
     * @param fileName The filename.
     * @param <T> The object type.
     *
     * @return the serializable object.
     */

    public static<T extends Serializable> T readSerializable(Context context, String fileName) {
        T objectToReturn = null;

        try {
            FileInputStream fileInputStream = context.openFileInput(fileName);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            objectToReturn = (T) objectInputStream.readObject();

            objectInputStream.close();
            fileInputStream.close();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        return objectToReturn;
    }

    /**
     * Removes a specified file.
     *
     * @param context The application context.
     * @param filename The name of the file.
     */

    public static void removeSerializable(Context context, String filename) {
        context.deleteFile(filename);
    }

}

7

त्रुटि हैंडलिंग और अतिरिक्त फ़ाइल स्ट्रीम के साथ पूरा कोड बंद हो जाता है। इसे अपनी कक्षा में शामिल करें जिसे आप क्रमबद्ध और निर्विवाद रूप से सक्षम बनाना चाहते हैं। मेरे मामले में वर्ग का नाम है CreateResumeForm। आपको इसे अपने स्वयं के वर्ग नाम में बदलना चाहिए। Androidइंटरफ़ेस Serializableआपके ऑब्जेक्ट को फ़ाइल में सहेजने के लिए पर्याप्त नहीं है, यह केवल स्ट्रीम बनाता है।

// Constant with a file name
public static String fileName = "createResumeForm.ser";

// Serializes an object and saves it to a file
public void saveToFile(Context context) {
    try {
        FileOutputStream fileOutputStream = context.openFileOutput(fileName, Context.MODE_PRIVATE);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(this);
        objectOutputStream.close();
        fileOutputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


// Creates an object by reading it from a file
public static CreateResumeForm readFromFile(Context context) {
    CreateResumeForm createResumeForm = null;
    try {
        FileInputStream fileInputStream = context.openFileInput(fileName);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        createResumeForm = (CreateResumeForm) objectInputStream.readObject();
        objectInputStream.close();
        fileInputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return createResumeForm;
}

इसे इस तरह से अपने में इस्तेमाल करें Activity:

form = CreateResumeForm.readFromFile(this);

0

मैं SharePrefrences का उपयोग करता हूं:

package myapps.serializedemo;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.io.IOException;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

//Create the SharedPreferences
    SharedPreferences sharedPreferences = this.getSharedPreferences("myapps.serilizerdemo", Context.MODE_PRIVATE);
    ArrayList<String> friends = new ArrayList<>();
    friends.add("Jack");
    friends.add("Joe");
    try {

 //Write / Serialize
 sharedPreferences.edit().putString("friends",
    ObjectSerializer.serialize(friends)).apply();
    } catch (IOException e) {
        e.printStackTrace();
    }
//READ BACK
    ArrayList<String> newFriends = new ArrayList<>();
    try {
        newFriends = (ArrayList<String>) ObjectSerializer.deserialize(
                sharedPreferences.getString("friends", ObjectSerializer.serialize(new ArrayList<String>())));
    } catch (IOException e) {
        e.printStackTrace();
    }
    Log.i("***NewFriends", newFriends.toString());
}
}

0

आप अपने कार्यक्रम में एक ObjectSerialization वर्ग जोड़ना होगा निम्नलिखित काम कर सकते हैं

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;

    public class ObjectSerializer {

public static String serialize(Serializable obj) throws IOException {
    if (obj == null) return "";
    try {
        ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
        ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
        objStream.writeObject(obj);
        objStream.close();
        return encodeBytes(serialObj.toByteArray());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public static Object deserialize(String str) throws IOException {
    if (str == null || str.length() == 0) return null;
    try {
        ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
        ObjectInputStream objStream = new ObjectInputStream(serialObj);
        return objStream.readObject();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public static String encodeBytes(byte[] bytes) {
    StringBuffer strBuf = new StringBuffer();

    for (int i = 0; i < bytes.length; i++) {
        strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
        strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
    }

    return strBuf.toString();
}

public static byte[] decodeBytes(String str) {
    byte[] bytes = new byte[str.length() / 2];
    for (int i = 0; i < str.length(); i+=2) {
        char c = str.charAt(i);
        bytes[i/2] = (byte) ((c - 'a') << 4);
        c = str.charAt(i+1);
        bytes[i/2] += (c - 'a');
    }
    return bytes;
}

}

यदि आप साझा उपयोग के साथ साझा करने के लिए उपयोग कर रहे हैं एक सरणी स्टोर करने के लिए निम्नलिखित के साथ: -

SharedPreferences sharedPreferences = this.getSharedPreferences(getPackageName(),MODE_PRIVATE);

सीरियल करने के लिए: -

sharedPreferences.putString("name",ObjectSerializer.serialize(array));

वर्णन करने के लिए: -

newarray = (CAST_IT_TO_PROPER_TYPE) ObjectSerializer.deSerialize(sharedPreferences.getString(name),null);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.