IO.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-4.2.0).
003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.util;
021 
022 import java.io.ByteArrayInputStream;
023 import java.io.ByteArrayOutputStream;
024 import java.io.File;
025 import java.io.FileInputStream;
026 import java.io.FileOutputStream;
027 import java.io.IOException;
028 import java.io.InputStream;
029 import java.io.ObjectInputStream;
030 import java.io.ObjectOutputStream;
031 import java.io.OutputStream;
032 import java.nio.file.Path;
033 
034 /**
035  * Class for object serialization. The following example shows how to write and
036  * reload a given population.
037  *
038  <pre>{@code
039  * // Creating result population.
040  * EvolutionResult<DoubleGene, Double> result = stream
041  *     .collect(toBestEvolutionResult());
042  *
043  * // Writing the population to disk.
044  * final File file = new File("population.bin");
045  * IO.object.write(result.getPopulation(), file);
046  *
047  * // Reading the population from disk.
048  * ISeq<Phenotype<G, C>> population = (ISeq<Phenotype<G, C>>)IO.object.read(file);
049  * EvolutionStream<DoubleGene, Double> stream = Engine
050  *     .build(ff, gtf)
051  *     .stream(population, 1);
052  * }</pre>
053  *
054  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
055  @since 1.0
056  @version 4.0
057  */
058 public abstract class IO {
059 
060     protected IO() {
061     }
062 
063     /**
064      * IO implementation for "native" <i>Java</i> serialization.
065      */
066     public static final IO object = new IO() {
067 
068         @Override
069         public void write(final Object object, final OutputStream out)
070             throws IOException
071         {
072             final ObjectOutputStream oout = new ObjectOutputStream(out);
073             oout.writeObject(object);
074             out.flush();
075         }
076 
077         @Override
078         public <T> T read(final Class<T> type, final InputStream in)
079             throws IOException
080         {
081             final ObjectInputStream oin = new ObjectInputStream(in);
082             try {
083                 return type.cast(oin.readObject());
084             catch (ClassNotFoundException | ClassCastException e) {
085                 throw new IOException(e);
086             }
087         }
088     };
089 
090     /**
091      * Serializes the given {@code object} to a {@code byte[]} array.
092      *
093      @since 4.1
094      *
095      @param object the object to serialize.
096      @throws NullPointerException if one of the object is {@code null}.
097      @throws IOException if the object could not be serialized.
098      @return the serialized {@code object} as {@code byte[]} array
099      */
100     public byte[] toByteArray(final Object objectthrows IOException {
101         final ByteArrayOutputStream out = new ByteArrayOutputStream();
102         write(object, out);
103         return out.toByteArray();
104     }
105 
106     /**
107      * Write the (serializable) object to the given path.
108      *
109      @param object the object to serialize.
110      @param path the path to write the object to.
111      @throws NullPointerException if one of the arguments is {@code null}.
112      @throws IOException if the object could not be serialized.
113      */
114     public void write(final Object object, final String path)
115         throws IOException
116     {
117         write(object, new File(path));
118     }
119 
120     /**
121      * Write the (serializable) object to the given path.
122      *
123      @param object the object to serialize.
124      @param path the path to write the object to.
125      @throws NullPointerException if one of the arguments is {@code null}.
126      @throws IOException if the object could not be serialized.
127      */
128     public void write(final Object object, final Path path)
129         throws IOException
130     {
131         write(object, path.toFile());
132     }
133 
134     /**
135      * Write the (serializable) object to the given file.
136      *
137      @param object the object to serialize.
138      @param file the file to write the object to.
139      @throws NullPointerException if one of the arguments is {@code null}.
140      @throws IOException if the object could not be serialized.
141      */
142     public void write(final Object object, final File file)
143         throws IOException
144     {
145         try (final FileOutputStream out = new FileOutputStream(file)) {
146             write(object, out);
147         }
148     }
149 
150     /**
151      * Write the (serializable) object to the given output stream.
152      *
153      @param object the object to serialize.
154      @param out the output stream to write the object to.
155      @throws NullPointerException if one of the arguments is {@code null}.
156      @throws IOException if the object could not be serialized.
157      */
158     public abstract void write(final Object object, final OutputStream out)
159         throws IOException;
160 
161     /**
162      * Creates a, previously serialized, object from the given {@code byte[]}
163      * array.
164      *
165      @since 4.1
166      *
167      @param bytes the serialized object.
168      @return the de-serialized object.
169      @throws NullPointerException if the input {@code bytes} is {@code null}.
170      @throws IOException if the object could not be de-serialized.
171      */
172     public Object fromByteArray(final byte[] bytesthrows IOException {
173         final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
174         return read(in);
175     }
176 
177     /**
178      * Reads an object from the given file.
179      *
180      @param <T> the type of the read object
181      @param path the path to read from.
182      @param type the type of the read object.
183      @return the de-serialized object.
184      @throws NullPointerException if the input stream {@code in} is {@code null}.
185      @throws IOException if the object could not be read.
186      */
187     public <T> T read(final Class<T> type, final String path)
188         throws IOException
189     {
190         try (final FileInputStream in = new FileInputStream(new File(path))) {
191             return read(type, in);
192         }
193     }
194 
195     /**
196      * Reads an object from the given file.
197      *
198      @param path the path to read from.
199      @return the de-serialized object.
200      @throws NullPointerException if the input stream {@code in} is {@code null}.
201      @throws IOException if the object could not be read.
202      */
203     public Object read(final String paththrows IOException {
204         return read(Object.class, path);
205     }
206 
207     /**
208      * Reads an object from the given file.
209      *
210      @param <T> the type of the read object
211      @param path the path to read from.
212      @param type the type of the read object.
213      @return the de-serialized object.
214      @throws NullPointerException if the input stream {@code in} is {@code null}.
215      @throws IOException if the object could not be read.
216      */
217     public <T> T read(final Class<T> type, final Path path)
218         throws IOException
219     {
220         try (final FileInputStream in = new FileInputStream(path.toFile())) {
221             return read(type, in);
222         }
223     }
224 
225     /**
226      * Reads an object from the given file.
227      *
228      @param path the path to read from.
229      @return the de-serialized object.
230      @throws NullPointerException if the input stream {@code in} is {@code null}.
231      @throws IOException if the object could not be read.
232      */
233     public Object read(final Path paththrows IOException {
234         return read(Object.class, path);
235     }
236 
237     /**
238      * Reads an object from the given file.
239      *
240      @param <T> the type of the read object
241      @param file the file to read from.
242      @param type the type of the read object.
243      @return the de-serialized object.
244      @throws NullPointerException if the input stream {@code in} is {@code null}.
245      @throws IOException if the object could not be read.
246      */
247     public <T> T read(final Class<T> type, final File file)
248         throws IOException
249     {
250         try (final FileInputStream in = new FileInputStream(file)) {
251             return read(type, in);
252         }
253     }
254 
255     /**
256      * Reads an object from the given file.
257      *
258      @param file the file to read from.
259      @return the de-serialized object.
260      @throws NullPointerException if the input stream {@code in} is {@code null}.
261      @throws IOException if the object could not be read.
262      */
263     public Object read(final File filethrows IOException {
264         return read(Object.class, file);
265     }
266 
267     /**
268      * Reads an object from the given input stream.
269      *
270      @param <T> the type of the read object
271      @param in the input stream to read from.
272      @param type the type of the read object.
273      @return the de-serialized object.
274      @throws NullPointerException if the input stream {@code in} is {@code null}.
275      @throws IOException if the object could not be read.
276      */
277     public abstract <T> T read(final Class<T> type, final InputStream in)
278         throws IOException;
279 
280     /**
281      * Reads an object from the given input stream.
282      *
283      @param in the input stream to read from.
284      @return the de-serialized object.
285      @throws NullPointerException if the input stream {@code in} is {@code null}.
286      @throws IOException if the object could not be read.
287      */
288     public Object read(final InputStream inthrows IOException {
289         return read(Object.class, in);
290     }
291 }