개체를 문자열로 직렬화하는 방법
오브젝트를 파일로 시리얼화한 후 다음 코드 스니펫과 같이 다시 복원할 수 있습니다.개체를 문자열로 직렬화하고 대신 데이터베이스에 저장하려고 합니다.누가 나를 도와줄 수 있나요?
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();
세르지오:
BLOB를 사용해야 합니다.그것은 JDBC와 함께 꽤 직설적이다.
당신이 올린 두 번째 코드의 문제는 인코딩입니다.또한 바이트를 인코딩하여 장애가 발생하지 않도록 해야 합니다.
그래도 스트링에 쓰려면 java.util을 사용하여 바이트를 인코딩할 수 있습니다.베이스 64
그래도 시리얼화된 데이터가 얼마나 걸릴지 모르기 때문에 CLOB를 데이터 유형으로 사용해야 합니다.
다음은 사용 방법의 예입니다.
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
주의: Java 7 이전 버전에서는 여기에서 원래 답변을 볼 수 있습니다.
FileOutputStream 대신 ByteArrayOutputStream에 데이터를 쓰는 것은 어떻습니까?
그렇지 않으면 XMLEncoder를 사용하여 개체를 시리얼화하고 XML을 유지한 후 XMLDecoder를 통해 역직렬화할 수 있습니다.
빠른 답변 감사합니다.저는 당신의 도움에 감사하기 위해 즉시 투표를 포기하겠습니다.저는 당신의 답변을 바탕으로 최선의 해결책을 코드화했습니다.
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 사용을 고려하지 않았습니다.
주의: 직렬화된 개체를 데이터베이스에 문자열로 저장하지 말고 바이트[]로 저장하라는 조언을 고려하겠습니다.
오브젝트를 문자열에서 변환하는 Java8 어프로치.OscarRyz의 답변에서 영감을 얻습니다.부호화 해제/인코딩의 경우 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();
}
}
}
XStream은 XML과의 시리얼화/디시리얼화를 위한 심플한 유틸리티를 제공합니다.또, 매우 고속입니다.바이너리 BLOBS가 아닌 XML CLOB를 저장하는 것은 읽기 쉬울 뿐만 아니라 취약성도 낮아집니다.
오브젝트를 블롭으로 유지하면 어떨까요?
"이러한 데이터"를.BLOB
【★】는 보다 할 수 염려가 . 및 합니다.JDBC는 스트림 측면에서 BLOB를 생성하고 검색하는 방법을 제공합니다.Java 6을 사용할 수 있다면, JDBC API에 몇 가지 추가 사항을 추가하여 블럽을 훨씬 쉽게 처리할 수 있도록 합니다.
데이터를 문자열로 저장해야 하는 경우 XML 기반 스토리지용 XStream을 권장합니다(보다 훨씬 간단함).XMLEncoder
대체 객체 표현도 마찬가지로 유용할 수 있습니다(예: JSON).접근 방식은 객체를 실제로 이런 방식으로 저장해야 하는 이유에 따라 달라집니다.
java.sql을 보세요.PreparedStatement 클래스, 특히 함수
그런 다음 java.sql을 살펴봅니다.ResultSet 클래스, 특히 함수
http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#getBinaryStream(int)
오브젝트를 데이터베이스로 시리얼화한 후 코드 내의 오브젝트를 새 버전으로 변경하는 경우 오브젝트의 시그니처가 변경되어 시리얼 해제 프로세스가 실패할 수 있습니다.커스텀 프리퍼런스를 시리얼화한 후 프리퍼런스 정의를 변경하는 실수를 한 적이 있습니다.갑자기 나는 이전에 연재된 정보를 읽을 수 없었다.
오브젝트 버전 및 역직렬화에서 이 문제를 방지하려면 테이블의 속성 열별로 투박하게 쓰고 대신 이 방법으로 오브젝트를 구성 및 분해하는 것이 좋습니다.또는 java.util과 같은 해시맵에 속성을 씁니다.Properties 오브젝트, 다음으로 변경할 가능성이 거의 없는 properties 오브젝트를 시리얼화합니다.
시리얼화된 스트림은 바이트(옥텟)의 시퀀스일 뿐입니다.여기서 문제는 바이트 시퀀스를 String으로 변환하고 다시 되돌리는 방법입니다.또한 데이터베이스에 저장하려면 제한된 문자 코드 집합을 사용해야 합니다.
이 문제에 대한 분명한 해결책은 필드를 이진 LOB로 변경하는 것입니다.문자 LOB를 계속 사용하려면 base64, 16진수, uu 등의 스킴으로 인코딩해야 합니다.
build in classs sun.misc 를 사용할 수 있습니다.Base64Decoder 및 sun.misc.Base64Serialize의 바이너리 데이터를 문자열로 변환하는 인코더.기본 제공되므로 추가 클래스가 필요하지 않습니다.
심플한 솔루션, 효과적
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(obj);
return out.toByteArray();
}
UUEencoding을 사용할 수 있습니다.
현재 가장 확실한 접근법은 객체를 JSON에 저장하는 것입니다.
- JSON을 읽을 수 있습니다.
- JSON은 XML보다 읽기 쉽고 작업하기 쉽습니다.
- JSON을 직접 저장할 수 있는 많은 비 SQL 데이터베이스.
- 클라이언트는 이미 JSON을 사용하여 서버와 통신하고 있습니다(그렇지 않으면 실수일 가능성이 높습니다).
Gson을 사용한 예.
Gson gson = new Gson();
Person[] persons = getArrayOfPersons();
String json = gson.toJson(persons);
System.out.println(json);
//output: [{"name":"Tom","age":11},{"name":"Jack","age":12}]
Person[] personsFromJson = gson.fromJson(json, Person[].class);
//...
class Person {
public String name;
public int age;
}
Gson은 List를 직접 변환할 수 있습니다.예시를 쉽게 검색할 수 있습니다.먼저 목록을 배열로 변환하는 것이 좋습니다.
언급URL : https://stackoverflow.com/questions/134492/how-to-serialize-an-object-into-a-string
'sourcecode' 카테고리의 다른 글
VeValidate를 사용하면 필드가 터치되어 유효한지 어떻게 확인할 수 있습니까? (0) | 2022.08.14 |
---|---|
vuex 모듈 사용 시 돌연변이를 테스트하는 방법 (0) | 2022.08.14 |
런타임에 Java 버전 가져오기 (0) | 2022.08.14 |
VueJS String 보간으로 TS 개체의 개인 속성에 액세스할 수 있습니다. (0) | 2022.08.14 |
값 0 대신 NULL을 사용할 수 있습니까? (0) | 2022.08.14 |