কীভাবে কোনও স্ট্রিংয়ে কোনও বস্তুকে সিরিয়ালাইজ করা যায়


150

আমি কোনও ফাইলে কোনও বস্তুকে সিরিয়ালাইজ করতে সক্ষম হয়েছি এবং তারপরে পরবর্তী কোড স্নিপেটে যেমন দেখানো হয়েছে তা আবার পুনরুদ্ধার করতে সক্ষম। আমি অবজেক্টটি একটি স্ট্রিংয়ে সিরিয়ালাইজ করতে এবং তার পরিবর্তে একটি ডাটাবেসে সংরক্ষণ করতে চাই। আমাকে কি কেউ সাহায্য করতে পারবেন?

LinkedList<Diff_match_patch.Patch> patches = // whatever...
FileOutputStream fileStream = new FileOutputStream("foo.ser");
ObjectOutputStream os = new ObjectOutputStream(fileStream);
os.writeObject(patches1);
os.close();

FileInputStream fileInputStream = new FileInputStream("foo.ser");
ObjectInputStream oInputStream = new ObjectInputStream(fileInputStream);
Object one = oInputStream.readObject();
LinkedList<Diff_match_patch.Patch> patches3 = (LinkedList<Diff_match_patch.Patch>) one;
os.close();

উত্তর:


270

সের্গিও:

আপনার BLOB ব্যবহার করা উচিত । এটি জেডিবিসি-র সাথে বেশ সোজা।

আপনার পোস্ট করা দ্বিতীয় কোডটির সমস্যা হ'ল এনকোডিং। এগুলির কোনওটিই ব্যর্থ না হয় তা নিশ্চিত করার জন্য আপনার অতিরিক্তভাবে বাইটগুলি এনকোড করা উচিত।

আপনি যদি এখনও এটি স্ট্রিংয়ে লিখতে চান তবে java.util.Base64 ব্যবহার করে বাইটগুলি এনকোড করতে পারেন ।

তবুও আপনার ডাটা টাইপ হিসাবে সিএলওবি ব্যবহার করা উচিত কারণ আপনি জানেন না যে সিরিয়ালযুক্ত ডেটা কতটা হতে চলেছে।

এটি কীভাবে ব্যবহার করবেন সে সম্পর্কে একটি নমুনা এখানে দেওয়া হল।

import java.util.*;
import java.io.*;

/** 
 * Usage sample serializing SomeClass instance 
 */
public class ToStringSample {

    public static void main( String [] args )  throws IOException,
                                                      ClassNotFoundException {
        String string = toString( new SomeClass() );
        System.out.println(" Encoded serialized version " );
        System.out.println( string );
        SomeClass some = ( SomeClass ) fromString( string );
        System.out.println( "\n\nReconstituted object");
        System.out.println( some );


    }

    /** Read the object from Base64 string. */
   private static Object fromString( String s ) throws IOException ,
                                                       ClassNotFoundException {
        byte [] data = Base64.getDecoder().decode( s );
        ObjectInputStream ois = new ObjectInputStream( 
                                        new ByteArrayInputStream(  data ) );
        Object o  = ois.readObject();
        ois.close();
        return o;
   }

    /** Write the object to a Base64 string. */
    private static String toString( Serializable o ) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream( baos );
        oos.writeObject( o );
        oos.close();
        return Base64.getEncoder().encodeToString(baos.toByteArray()); 
    }
}

/** Test subject. A very simple class. */ 
class SomeClass implements Serializable {

    private final static long serialVersionUID = 1; // See Nick's comment below

    int i    = Integer.MAX_VALUE;
    String s = "ABCDEFGHIJKLMNOP";
    Double d = new Double( -1.0 );
    public String toString(){
        return  "SomeClass instance says: Don't worry, " 
              + "I'm healthy. Look, my data is i = " + i  
              + ", s = " + s + ", d = " + d;
    }
}

আউটপুট:

C:\samples>javac *.java

C:\samples>java ToStringSample
Encoded serialized version
rO0ABXNyAAlTb21lQ2xhc3MAAAAAAAAAAQIAA0kAAWlMAAFkdAASTGphdmEvbGFuZy9Eb3VibGU7T
AABc3QAEkxqYXZhL2xhbmcvU3RyaW5nO3hwf////3NyABBqYXZhLmxhbmcuRG91YmxlgLPCSilr+w
QCAAFEAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cL/wAAAAAAAAdAAQQUJ
DREVGR0hJSktMTU5PUA==


Reconstituted object
SomeClass instance says: Don't worry, I'm healthy. Look, my data is i = 2147483647, s = ABCDEFGHIJKLMNOP, d = -1.0

দ্রষ্টব্য : জাভা 7 এর জন্য এবং তার আগে আপনি এখানে মূল উত্তরটি দেখতে পাবেন


আপনার পছন্দসই স্ট্রিংগুলির প্রয়োজন হলে +1, তারপরে বেস 64 + খড়ক the
জন গার্ডনার 19

6
+1, ছোট উন্নতি। টু স্ট্রিং () পদ্ধতিতে প্লেইন অবজেক্টের পরিবর্তে ইন্টারফেস সিরিয়ালাইজেবল ব্যবহার করা আরও ভাল: ব্যক্তিগত স্ট্যাটিক স্ট্রিং
টু

4
যদি আমরা স্ট্রিংয়ের পরিবর্তে অবজেক্টটি বাইট অ্যারে হিসাবে সংরক্ষণ করার চেষ্টা করি তবে আমরা BASE64 ব্যবহার না করে একই জিনিস অর্জন করতে পারি।
সুদার

2
এর মধ্যে মারাত্মক ত্রুটি হ'ল শ্রেণীর সংজ্ঞাগুলি সময়ের সাথে সাথে পরিবর্তিত হয় - যদি এই ধরনের পরিবর্তন ঘটে থাকে তবে আপনি deserialize করতে পারবেন না! একটি যুক্ত serialVersionUIDকরা SomeClassনতুন ক্ষেত্রগুলি যুক্ত হওয়ার বিরুদ্ধে সুরক্ষা দেবে তবে ক্ষেত্রগুলি সরিয়ে ফেলা হলে আপনার ক্ষতি হবে। কার্যকর জাভাতে এই বিষয়ে জোশুয়া ব্লচের কী বক্তব্য রয়েছে তা পড়া মূল্যহীন - books.google.co.uk/…
নিক হল্ট

1
জাভা 8 এর পর থেকে এখন java.util.Base64 রয়েছে। আপনার উত্তরটি আপডেট করা উচিত: বেস64.getEncoder ()। EncodeToString (baos.toByteArray ()); Base64.getDecoder () ডিকোড (গুলি)।
drUniversalis

12

কোনও ফাইলআউটপুট স্ট্রিমের পরিবর্তে বাইটআর্যআউটপুট স্ট্রিমে ডেটা লেখার বিষয়ে কীভাবে?

অন্যথায়, আপনি এক্সএমএলএনসিএনডার ব্যবহার করে অবজেক্টটি সিরিয়ালাইজ করতে পারবেন, এক্সএমএলটি অবিরত রাখতে পারবেন, তারপরে এক্সএমএলডেকোডারটির মাধ্যমে ডিসরিয়ালাইজ করতে পারবেন।


8

দুর্দান্ত এবং দ্রুত উত্তরের জন্য ধন্যবাদ। আমি আপনার সহায়তা স্বীকার করার জন্য অবিলম্বে কিছু ভোট দেব। আপনার উত্তরগুলির উপর ভিত্তি করে আমি আমার মতে সেরা সমাধানটি কোড করেছি।

LinkedList<Patch> patches1 = diff.patch_make(text2, text1);
try {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(bos);
    os.writeObject(patches1);
    String serialized_patches1 = bos.toString();
    os.close();


    ByteArrayInputStream bis = new ByteArrayInputStream(serialized_patches1.getBytes());
    ObjectInputStream oInputStream = new ObjectInputStream(bis);
    LinkedList<Patch> restored_patches1 = (LinkedList<Patch>) oInputStream.readObject();            



        // patches1 equals restored_patches1
    oInputStream.close();
} catch(Exception ex) {
    ex.printStackTrace();
}

দ্রষ্টব্য আমি JSON ব্যবহার করা বিবেচনা করি নি কারণ কম দক্ষ।

দ্রষ্টব্য: আমি ডাটাবেসে স্ট্রিং হিসাবে সিরিয়ালযুক্ত বস্তু সংরক্ষণ না করে বাইট [] পরিবর্তে আপনার পরামর্শ বিবেচনা করব।


3
"বাইটআরআউটআউটপুট স্ট্রিম.টো স্ট্রিং প্ল্যাটফর্মের ডিফল্ট এনকোডিং ব্যবহার করে রূপান্তর করে you আপনি কি নিশ্চিত যে আপনি এটি চান? বিশেষত একটি স্বেচ্ছাচারিত বাইট অ্যারে বৈধ ইউটিএফ 8 নয়। আরও, ডেটাবেসটি ম্যাঙ্গাল করতে চলেছে।"
টম হাটিন -

টম হাটিনের উপরের মন্তব্যটি আপনার গুরুত্ব সহকারে নেওয়া উচিত
অঞ্জনব

সিরিয়ালযুক্ত বস্তুর দীর্ঘমেয়াদী স্টোরেজ উল্লেখ না করা কোনও দুর্দান্ত ধারণা নয় এবং প্রস্তাবিত নয়
স্টিভ জি

"দ্রষ্টব্য আমি JSON ব্যবহার করা বিবেচনা করি নি কারণ কম দক্ষ" " দক্ষতার জন্য গুগলের প্রোটোকল বাফার ব্যবহার সম্পর্কে কীভাবে? এছাড়াও, স্টিভ জি এর ধারণা নিখুঁত ধারণা দেয়। কোনও ডিবিতে সিরিয়ালযুক্ত ডেটা সংরক্ষণ করার একটি উপায় যা জাভা ব্যতীত অন্য ভাষাগুলির জন্য এটি উপলভ্য করে তা আবার প্রোটোকল বাফার।
অঞ্জনব

5

জাভা 8 পদ্ধতির, অবজেক্টকে স্ট্রিং থেকে / এ স্ট্রিংয়ে রূপান্তর করা, অস্কাররাইজের উত্তর থেকে অনুপ্রাণিত । ডি- / এনকোডিংয়ের জন্য java.util.Base64 প্রয়োজনীয় এবং ব্যবহৃত হয়।

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Base64;
import java.util.Optional;

final class ObjectHelper {

  private ObjectHelper() {}

  static Optional<String> convertToString(final Serializable object) {
    try (final ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos)) {
      oos.writeObject(object);
      return Optional.of(Base64.getEncoder().encodeToString(baos.toByteArray()));
    } catch (final IOException e) {
      e.printStackTrace();
      return Optional.empty();
    }
  }

  static <T extends Serializable> Optional<T> convertFrom(final String objectAsString) {
    final byte[] data = Base64.getDecoder().decode(objectAsString);
    try (final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {
      return Optional.of((T) ois.readObject());
    } catch (final IOException | ClassNotFoundException e) {
      e.printStackTrace();
      return Optional.empty();
    }
  }
}

এটি কেন একটি শ্রেণীর চেয়ে ইন্টারফেস?
সিমোনালেক্সান্ডার 20055

@ সিমোনালেক্সান্ডার 20055 অর্থপূর্ণ দ্রষ্টব্য, আমি এখানে আর কোনও ইন্টারফেস ব্যবহার করব না। আমি এটি পরিবর্তন করেছিলাম.
মার্কাস শুল্টে

4

এক্সস্ট্রিএম এক্সএমএল থেকে / থেকে সিরিয়ালাইজেশন / ডিসিরিয়ালাইজ করার জন্য একটি সহজ ইউটিলিটি সরবরাহ করে এবং এটি খুব দ্রুত। বাইনারি বিএলবিএসের পরিবর্তে এক্সএমএল সিএলওবিগুলি সংরক্ষণ করা কম ভঙ্গুর হতে চলেছে, বেশি পাঠযোগ্য বলে উল্লেখ করার দরকার নেই।



3

আপনি যদি ডাটাবেসে বাইনারি ডেটা হিসাবে কোনও বিষয় সংরক্ষণ করছেন, তবে আপনার সত্যিকার অর্থে একটি BLOBডেটাটাইপ ব্যবহার করা উচিত । ডাটাবেস এটিকে আরও দক্ষতার সাথে সঞ্চয় করতে সক্ষম এবং আপনার এনকোডিংগুলি এবং এর মতো বিষয়ে চিন্তা করতে হবে না। জেডিবিসি স্ট্রিমের ক্ষেত্রে ব্লব তৈরি এবং পুনরুদ্ধারের জন্য পদ্ধতি সরবরাহ করে। জাভা 6 ব্যবহার করুন যদি আপনি পারেন তবে এটি জেডিবিসি এপিআইতে কিছু সংযোজন করেছে যা ব্লবগুলির সাথে ডিলগুলি পুরোপুরি সহজ করে তোলে।

আপনার যদি স্ট্রিং হিসাবে ডেটা সঞ্চয় করার প্রয়োজন হয় তবে আমি এক্সএমআল ভিত্তিক স্টোরেজ (এর চেয়ে অনেক সহজ XMLEncoder) এর জন্য এক্সস্ট্রিমের পরামর্শ দেব , তবে বিকল্প অবজেক্টের উপস্থাপনা ঠিক তত কার্যকর হতে পারে (যেমন জেএসএন)। আপনার পদ্ধতির উপর নির্ভর করে কেন আপনাকে আসলে এইভাবে জিনিসটি সঞ্চয় করতে হবে।


2

Java.sql.PreparedStatement ক্লাসটি দেখুন, বিশেষত ফাংশনটি

http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setBinaryStream(int,%20java.io.InputStream)

তারপরে java.sql.ResultSet বর্গটি দেখুন, বিশেষত ফাংশনটি

http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#getBinaryStream(int)

মনে রাখবেন যে আপনি যদি কোনও বস্তুকে ডাটাবেসে সিরিয়াল করে তুলছেন এবং তারপরে আপনি আপনার কোডে কোনও নতুন সংস্করণে এই অবজেক্টটি পরিবর্তন করেন, তখন আপনার অজেক্টের স্বাক্ষর পরিবর্তিত হওয়ায় ডেসিরিয়ালাইজেশন প্রক্রিয়াটি সহজেই ব্যর্থ হতে পারে। আমি একবার কাস্টম পছন্দগুলি সিরিয়ালযুক্ত সংরক্ষণ করে এবং তারপরে পছন্দগুলি সংজ্ঞাটিতে পরিবর্তন করে এই ভুলটি করেছি। হঠাৎ আমি আগের সিরিয়ালযুক্ত কোনও তথ্য পড়তে পারি নি।

আপনি কোনও টেবিলে সম্পত্তি কলামে ক্লঙ্কি লিখতে এবং পরিবর্তে অবজেক্টের সংস্করণ এবং deserialization সহ এই সমস্যাটি এড়াতে পরিবর্তে এইভাবে অবজেক্টটি রচনা এবং পচন করা ভাল। বা java.util.Pererties অবজেক্টের মতো কোনও ধরণের হ্যাশম্যাপে বৈশিষ্ট্যগুলি লিখতে এবং তারপরে বৈশিষ্ট্যগুলির অবজেক্টটি সিরিয়ালাইজ করে যা পরিবর্তনের পক্ষে খুব কমই।


1

সিরিয়ালযুক্ত স্ট্রিমটি বাইট (অক্টেটস) এর কেবল একটি ক্রম। সুতরাং প্রশ্নটি কীভাবে বাইটের ক্রমকে স্ট্রিংয়ে রূপান্তর করতে হয় এবং আবার ফিরে যায়। আরও এটি অক্ষর কোডের একটি সীমিত সেট ব্যবহার করা প্রয়োজন যদি এটি কোনও ডাটাবেসে সংরক্ষণ করা হয়।

সমস্যার স্পষ্ট সমাধান হ'ল ক্ষেত্রটি বাইনারি এলওবিতে পরিবর্তন করা। আপনি যদি চ্যারিসর এলওবি দিয়ে আটকাতে চান তবে আপনাকে বেস 64, হেক্স বা ইউউ এর মতো কিছু স্কিমে এনকোড করতে হবে।


1

সিরিয়ালাইজের বাইনারি ডেটা স্ট্রিংয়ে রূপান্তর করতে আপনি sun.misc.Base64Decoder এবং sun.misc.Base64Encoder এ ক্লাসে বিল্ডটি ব্যবহার করতে পারেন। আপনার অতিরিক্ত ক্লাসের দরকার নেই কারণ এটি অন্তর্নির্মিত।


0

আপনি ইউইউ কোডিং ব্যবহার করতে পারেন


0

সিম্পল সলিউশন, আমার জন্য কাজ করেছে

public static byte[] serialize(Object obj) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(out);
    os.writeObject(obj);
    return out.toByteArray();
}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.