ورود

View Full Version : سوال: ایجاد فایلهای با پسوند serialized در جاوا



sooren_66
شنبه 18 مهر 1394, 16:33 عصر
سلام دوستان ایجاد فایلهای با پسوند serialized در جاوا چگونه است؟؟؟

محمد فدوی
شنبه 18 مهر 1394, 22:07 عصر
منظورت رو از «فایلهای با پسوند serialized» باید روشن‌تر می‌گفتی.
ولی اگر منظورت اینه که می‌خوای یه شء رو سریالی کنی و توی یه فایل ذخیره کنی، خیلی ساده می‌تونی با ابزارهای ورودی/خروجی جاوا این‌کار رو بکنی.
لینک (http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/)

sooren_66
سه شنبه 21 مهر 1394, 18:06 عصر
منظورت رو از «فایلهای با پسوند serialized» باید روشن‌تر می‌گفتی.
ولی اگر منظورت اینه که می‌خوای یه شء رو سریالی کنی و توی یه فایل ذخیره کنی، خیلی ساده می‌تونی با ابزارهای ورودی/خروجی جاوا این‌کار رو بکنی.
لینک (http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/)
سلام ممنون از پاسخ می خواستم چندین شی رو پیاده سازی کنم ولی نمی دونم به چه صورت فقط می دونم باید پسوندش serialized باشه.لطفا راهنمایی کنین

محمد فدوی
سه شنبه 21 مهر 1394, 20:26 عصر
اگر لینکی که دادم رو مطالعه کنی سریالی کردن یه شیء رو خیلی خوب یاد می‌گیری. یه مثال می‌زنم. کلاس Account رو به این شکل داریم:
public class Account implements Serializable {
private final String firstname;
private final String lastname;

public Account(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}

public String getFirstname() {
return firstname;
}

public String getLastname() {
return lastname;
}

public @Override
String toString() {
return "Firstname: " + firstname
+ ", Lastname: " + lastname;
}
}
و می‌خوایم یک شیء رو از این کلاس سریالی (Serialize) و دِسریالی (Deserialize) کنیم. وقتی یک شیء رو توی یک فایل (یا هر خروجی دیگه‌ای) بنویسیم اون رو Serialize کردیم و هروقت یک شیء رو از محتویات یک فایل بازسازی کنیم اون رو Deserialize کردیم. برای این‌کار دوتا متد ساده به همین نام‌ها تعریف می‌کنیم و از اون‌ها توی متد main استفاده می‌کنیم:
public class SerializePractice {
private static void serialize(Object obj, String filename) throws IOException {
try(FileOutputStream fos = new FileOutputStream(filename);
BufferedOutputStream buff = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(buff)) {

oos.writeObject(obj);
}
}

private static Object deserialize(String filename) throws IOException, ClassNotFoundException {
try(FileInputStream fis = new FileInputStream(filename);
BufferedInputStream buff = new BufferedInputStream(fis);
ObjectInputStream ois = new ObjectInputStream(buff)) {

return ois.readObject();
}
}

public static void main(String[] args) {
final String FILE_NAME = "D:/richard.ser";

//
// 1. Serialize
//
Account richard1 = new Account("Richard", "Stallman");

try {
serialize(richard1, FILE_NAME);
} catch(IOException ex) {
out.println("Serialize failed! :(");
return;
}

//
// 2. Deserialize
//
Account richard2;

try {
richard2 = (Account) deserialize(FILE_NAME);
} catch(IOException | ClassNotFoundException | ClassCastException ex) {
out.println("Deserialize failed! :(");
return;
}

out.println(richard2);

//
// OUTPUT:
// Firstname: Richard, Lastname: Stallman
//
}
}
که فهم کد هم به نظر ساده‌ست.

ویرایش: برای اجرا کردن کد نیاز به جاوا ۷ یا جدیدتر دارید. اگر از جاوا ۶ استفاده می‌کنید باید یه تغییرات اندکی توی کد داده بشه...

ahmad.mo74
چهارشنبه 22 مهر 1394, 16:52 عصر
سلام.

اگر با آبجکت های بزرگ و پیچیده سروکار دارید و یا performance و حجم فایل خروجی براتون مهمه، یه لایبرری خوبی وجود داره که به نظرم بهترین هست برای اینکار و خودم هم همشه ازش استفاده میکنم.

Kryo (https://github.com/EsotericSoftware/kryo)

من یه تستی انجام دادم :


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


/**
* @author ahmad
*/
public class SerializerTest {


public static void main(String[] args) throws Exception {
Movie movie = buildComplexObject();
int iterationCount = 1000;


// warm up
System.out.println("warm up...");
for (int i = 0; i < iterationCount; i++) {
testKryo(movie);
testJavaSerializer(movie);
}


System.out.println("test started...");


// kryo
long start = System.currentTimeMillis();
for (int i = 0; i < iterationCount; i++) {
if (!testKryo(movie)) {
System.err.println("Kryo TEST FAILED!");
break;
}
}
long end = System.currentTimeMillis();
System.out.printf("Kryo test took %d ms%n", end - start);


// JavaSerializer
start = System.currentTimeMillis();
for (int i = 0; i < iterationCount; i++) {
if (!testJavaSerializer(movie)) {
System.err.println("JavaSerializer TEST FAILED!");
break;
}
}
end = System.currentTimeMillis();
System.out.printf("JavaSerializer test took %d ms%n", end - start);
}


private static boolean testKryo(Movie movie) throws IOException {
String source = "D:/movie_kryo.ser";
try (ObjectSerializer<Movie> movieSerializer = new ObjectSerializer<>(source, Movie.class, movie, false)) {
movieSerializer.flushToDisk();
return movie.equals(movieSerializer.loadFromDisk());
}
}


private static boolean testJavaSerializer(Movie movie) throws IOException, ClassNotFoundException {
String source = "D:/movie.ser";
try (ObjectOutputStream outputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(source)))) {
outputStream.writeObject(movie);
}
try (ObjectInputStream inputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(source)))) {
return movie.equals(inputStream.readObject());
}
}


private static Movie buildComplexObject() {
Director director = new Director("director directory", new Date(), Gender.MALE);
Movie movie = new Movie("My Movie 2016", new Date(), 120 * 60 * 1000, director);
director.getMovies().add(movie);
for (int i = 0; i < 1000; i++) {
Actor actor = new Actor("actor " + (i + 1), new Date(), i % 2 == 0 ? Gender.MALE : Gender.FEMALE);
movie.getActors().add(actor);
actor.getMovies().add(movie);
}
return movie;
}


}


خروجی تست :


warm up...
test started...
Kryo test took 2067 ms
JavaSerializer test took 2949 ms


Artist.java :


import java.io.Serializable;import java.util.Date;
import java.util.Objects;


/**
* @author ahmad
*/
public class Artist implements Serializable {


private String fullName;
private Date birthDate;
private Gender gender;


public Artist() {
}


public Artist(String fullName, Date birthDate, Gender gender) {
this.fullName = fullName;
this.birthDate = birthDate;
this.gender = gender;
}


public String getFullName() {
return fullName;
}


public void setFullName(String fullName) {
this.fullName = fullName;
}


public Date getBirthDate() {
return birthDate;
}


public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}


public Gender getGender() {
return gender;
}


public void setGender(Gender gender) {
this.gender = gender;
}


@Override
public int hashCode() {
return Objects.hash(fullName, birthDate, gender);
}


@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !(obj instanceof Artist)) {
return false;
}
Artist that = (Artist) obj;
return fullName.equals(that.fullName) && birthDate.equals(that.birthDate) && gender == that.gender;
}


@Override
public String toString() {
return "{" +
"fullName='" + fullName + '\'' +
", birthDate=" + birthDate +
", gender=" + gender +
'}';
}


}


Gender.java :

public enum Gender {

MALE, FEMALE

}


Actor.java :


import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;


/**
* @author ahmad
*/
public class Actor extends Artist implements Serializable {


private Set<Movie> movies;


public Actor() {
}


public Actor(Set<Movie> movies) {
this.movies = movies;
}


public Actor(String fullName, Date birthDate, Gender gender) {
super(fullName, birthDate, gender);
}


public Actor(String fullName, Date birthDate, Gender gender, Set<Movie> movies) {
super(fullName, birthDate, gender);
this.movies = movies;
}


public Set<Movie> getMovies() {
if (movies == null) {
movies = new HashSet<>();
}
return movies;
}


public void setMovies(Set<Movie> movies) {
this.movies = movies;
}


}


Director.java :


import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;


/**
* @author ahmad
*/
public class Director extends Artist implements Serializable {


private Set<Movie> movies;


public Director() {
}


public Director(Set<Movie> movies) {
this.movies = movies;
}


public Director(String fullName, Date birthDate, Gender gender) {
super(fullName, birthDate, gender);
}


public Director(String fullName, Date birthDate, Gender gender, Set<Movie> movies) {
super(fullName, birthDate, gender);
this.movies = movies;
}


public Set<Movie> getMovies() {
if (movies == null) {
movies = new HashSet<>();
}
return movies;
}


public void setMovies(Set<Movie> movies) {
this.movies = movies;
}


}


Movie.java :


import java.io.Serializable;import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;


/**
* @author ahmad
*/
public class Movie implements Serializable {


private String name;
private Date creationDate;
private long duration;
private Director director;
private Set<Actor> actors;


public Movie() {
}


public Movie(String name, Date creationDate, long duration, Director director) {
this.name = name;
this.creationDate = creationDate;
this.duration = duration;
this.director = director;
}


public Movie(String name, Date creationDate, long duration, Director director, Set<Actor> actors) {
this.name = name;
this.creationDate = creationDate;
this.duration = duration;
this.director = director;
this.actors = actors;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public Date getCreationDate() {
return creationDate;
}


public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}


public long getDuration() {
return duration;
}


public void setDuration(long duration) {
this.duration = duration;
}


public Director getDirector() {
return director;
}


public void setDirector(Director director) {
this.director = director;
}


public Set<Actor> getActors() {
if (actors == null) {
actors = new HashSet<>();
}
return actors;
}


public void setActors(Set<Actor> actors) {
this.actors = actors;
}


@Override
public int hashCode() {
return Objects.hash(name, creationDate, duration, director, actors);
}


@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !(obj instanceof Movie)) {
return false;
}
Movie that = (Movie) obj;
return name.equals(that.name) && creationDate.equals(that.creationDate)
&& duration == that.duration && director.equals(that.director) && actors.equals(that.actors);
}


@Override
public String toString() {
return "{" +
"name='" + name + '\'' +
", creationDate=" + creationDate +
", duration=" + duration +
", director=" + director +
", actors=" + actors +
'}';
}


}


ObjectSerializer.java :

import com.esotericsoftware.kryo.Kryo;import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;


import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicReferenceFieldUp dater;


/**
* @author ahmad
*/
public final class ObjectSerializer<T> implements AutoCloseable {


private volatile T value;
private final String source;
private final Class<T> type;
private final AtomicReferenceFieldUpdater<ObjectSerializer, Object> valueUpdater;
private final boolean deleteOnClose;
private final Kryo kryo = new Kryo();


private Input input;


public ObjectSerializer(String source, Class<T> type) {
this(source, type, null, true);
}


public ObjectSerializer(String source, Class<T> type, T value) {
this(source, type, value, true);
}


public ObjectSerializer(String source, Class<T> type, boolean deleteOnClose) {
this(source, type, null, deleteOnClose);
}


public ObjectSerializer(String source, Class<T> type, T value, boolean deleteOnClose) {
this.source = source;
this.type = type;
this.value = value;
this.deleteOnClose = deleteOnClose;
valueUpdater = AtomicReferenceFieldUpdater.newUpdater(ObjectSeria lizer.class, Object.class, "value");
kryo.register(type);
}


public String getSource() {
return source;
}


public Class<T> getType() {
return type;
}


public T get() {
return value;
}


public void set(T value) {
valueUpdater.set(this, value);
}


public <S> void register(Class<S> type) {
kryo.register(type);
}


public <S> void register(Class<S> type, int id) {
kryo.register(type, id);
}


public <S> void register(Class<S> type, Serializer<S> serializer) {
kryo.register(type, serializer);
}


public <S> void register(Class<S> type, Serializer<S> serializer, int id) {
kryo.register(type, serializer, id);
}


public void flushToDisk() throws FileNotFoundException {
final T t = value;
if (t != null) {
serialize(t);
set(null);
}
}


public T loadFromDisk() throws FileNotFoundException {
final T newValue = deserialize();
set(newValue);
return newValue;
}


private synchronized void serialize(T t) throws FileNotFoundException {
closeInput();
try (Output output = new Output(new BufferedOutputStream(new FileOutputStream(source)))) {
kryo.writeObject(output, t);
}
openInput();
}


private synchronized T deserialize() throws FileNotFoundException {
openInput();
return kryo.readObject(input, type);
}


private void openInput() throws FileNotFoundException {
if (input == null) {
input = new Input(new BufferedInputStream(new FileInputStream(source)));
}
}


private void closeInput() {
if (input != null) {
input.close();
input = null;
}
}


@Override
public boolean equals(Object obj) {
return this == obj || obj != null && obj instanceof ObjectSerializer && source.equals(((ObjectSerializer) obj).source);
}


@Override
public int hashCode() {
return source.hashCode();
}


@Override
public void close() throws IOException {
set(null);
closeInput();
if (deleteOnClose) {
Files.delete(Paths.get(source));
}
}


}


(برای کار با Kryo لازم نیست آبجکت هامون Serializable رو implements کنن)

محمد فدوی
چهارشنبه 22 مهر 1394, 17:34 عصر
(برای کار با Kryo لازم نیست آبجکت هامون Serializable رو implements کنن)
جالب بود. البته همونطور که گفتی به حجم داده‌ها هم خیلی بستگی داره. اما در مورد واسط Serializable، موقع استفاده از ObjectOutputStream هم نیازی نیست که واسط Serializable پیاده‌سازی شده باشه. کار این واسط فقط تاکید روی اینه که این شیء قابلیت سریالی شدن رو داره.

[younes]
پنج شنبه 23 مهر 1394, 12:38 عصر
موقع استفاده از ObjectOutputStream هم نیازی نیست که واسط Serializable پیاده‌سازی شده باشه. کار این واسط فقط تاکید روی اینه که این شیء قابلیت سریالی شدن رو داره.
فکر میکنم این طور نباشه چون یک جایی خوندم باید این واسط پیاده سازی بشه .
اگر ممکنه مثال نقضی بیارید.