객체를 파일로 직렬화 한 다음 다음 코드 스 니펫에 표시된 것처럼 다시 복원 할 수 있습니다. 객체를 문자열로 직렬화하고 대신 데이터베이스에 저장하고 싶습니다. 누구든지 나를 도울 수 있습니까?
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.Base64를 사용하여 바이트를 인코딩 할 수 있습니다 .
직렬화 된 데이터의 길이를 모르기 때문에 여전히 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
답변
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 사용을 고려하지 않았습니다.
참고 : 직렬화 된 객체를 데이터베이스에 문자열로 저장하지 않고 대신 byte []에 대한 조언을 고려할 것입니다.
답변
에서 대답에서 영감을 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는 스트림 측면에서 블롭을 작성하고 검색하는 메소드를 제공합니다. 가능하면 Java 6을 사용하면 JDBC API를 추가하여 얼룩을 훨씬 쉽게 처리 할 수 있습니다.
데이터를 String으로 저장 해야하는 경우 XML 기반 스토리지 용 XStream 을 권장 XMLEncoder
하지만 () 보다 대체 객체 표현이 유용 할 수 있습니다 (예 : JSON). 이 방법으로 실제로 객체를 저장해야하는 이유에 따라 접근 방식이 달라집니다.
