001 /*
002 * Java Genetic Algorithm Library (jenetics-1.5.0).
003 * Copyright (c) 2007-2013 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@gmx.at)
019 */
020 package org.jenetics.util;
021
022 import java.io.File;
023 import java.io.FileInputStream;
024 import java.io.FileOutputStream;
025 import java.io.IOException;
026 import java.io.InputStream;
027 import java.io.ObjectInputStream;
028 import java.io.ObjectOutputStream;
029 import java.io.OutputStream;
030 import java.nio.file.Path;
031
032 import javolution.xml.XMLObjectReader;
033 import javolution.xml.XMLObjectWriter;
034 import javolution.xml.stream.XMLStreamException;
035
036 /**
037 * Class for object serialization. The following example shows how to write and
038 * reload a given population.
039 *
040 * [code]
041 * // Writing the population to disk.
042 * final File file = new File("population.xml");
043 * IO.xml.write(ga.getPopulation(), file);
044 *
045 * // Reading the population from disk.
046 * final Population<Float64Gene,Float64> population =
047 * (Population<Float64Gene, Float64)IO.xml.read(file);
048 * ga.setPopulation(population);
049 * [/code]
050 *
051 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
052 * @since 1.0
053 * @version 1.0 — <em>$Date: 2013-12-08 $</em>
054 */
055 public abstract class IO {
056
057 protected IO() {
058 }
059
060 /**
061 * IO implementation for <i>XML</i> serialization.
062 */
063 public static final IO xml = new IO() {
064
065 @Override
066 public void write(final Object object, final OutputStream out)
067 throws IOException
068 {
069 try {
070 final OutputStream nco = new NonClosableOutputStream(out);
071 final XMLObjectWriter writer = XMLObjectWriter.newInstance(nco);
072 writer.setIndentation("\t");
073 try {
074 writer.write(object);
075 writer.flush();
076 } finally {
077 writer.reset();
078 }
079 } catch (XMLStreamException e) {
080 throw new IOException(e);
081 }
082 }
083
084 @Override
085 public <T> T read(final Class<T> type, final InputStream in)
086 throws IOException
087 {
088 try {
089 final InputStream nci = new NonClosableInputStream(in);
090 final XMLObjectReader reader = XMLObjectReader.newInstance(nci);
091 try {
092 return type.cast(reader.read());
093 } finally {
094 reader.reset();
095 }
096 } catch (XMLStreamException e) {
097 throw new IOException(e);
098 }
099 }
100 };
101
102 /**
103 * IO implementation for "native" <i>Java</i> serialization.
104 */
105 public static IO object = new IO() {
106
107 @Override
108 public void write(final Object object, final OutputStream out)
109 throws IOException
110 {
111 final ObjectOutputStream oout = new ObjectOutputStream(out);
112 oout.writeObject(object);
113 out.flush();
114 }
115
116 @Override
117 public <T> T read(final Class<T> type, final InputStream in)
118 throws IOException
119 {
120 final ObjectInputStream oin = new ObjectInputStream(in);
121 try {
122 return type.cast(oin.readObject());
123 } catch (ClassNotFoundException | ClassCastException e) {
124 throw new IOException(e);
125 }
126 }
127 };
128
129
130 /**
131 * Write the (serializable) object to the given path.
132 *
133 * @param object the object to serialize.
134 * @param path the path to write the object to.
135 * @throws NullPointerException if one of the arguments is {@code null}.
136 * @throws IOException if the object could not be serialized.
137 */
138 public void write(final Object object, final String path)
139 throws IOException
140 {
141 write(object, new File(path));
142 }
143
144 /**
145 * Write the (serializable) object to the given path.
146 *
147 * @param object the object to serialize.
148 * @param path the path to write the object to.
149 * @throws NullPointerException if one of the arguments is {@code null}.
150 * @throws IOException if the object could not be serialized.
151 */
152 public void write(final Object object, final Path path)
153 throws IOException
154 {
155 write(object, path.toFile());
156 }
157
158 /**
159 * Write the (serializable) object to the given file.
160 *
161 * @param object the object to serialize.
162 * @param file the file to write the object to.
163 * @throws NullPointerException if one of the arguments is {@code null}.
164 * @throws IOException if the object could not be serialized.
165 */
166 public void write(final Object object, final File file)
167 throws IOException
168 {
169 try (final FileOutputStream out = new FileOutputStream(file)) {
170 write(object, out);
171 }
172 }
173
174 /**
175 * Write the (serializable) object to the given output stream.
176 *
177 * @param object the object to serialize.
178 * @param out the output stream to write the object to.
179 * @throws NullPointerException if one of the arguments is {@code null}.
180 * @throws IOException if the object could not be serialized.
181 */
182 public abstract void write(final Object object, final OutputStream out)
183 throws IOException;
184
185 /**
186 * Reads an object from the given file.
187 *
188 * @param path the path to read from.
189 * @param type the type of the read object.
190 * @return the de-serialized object.
191 * @throws NullPointerException if the input stream {@code in} is {@code null}.
192 * @throws IOException if the object could not be read.
193 */
194 public <T> T read(final Class<T> type, final String path)
195 throws IOException
196 {
197 try (final FileInputStream in = new FileInputStream(new File(path))) {
198 return read(type, in);
199 }
200 }
201
202 /**
203 * Reads an object from the given file.
204 *
205 * @param path the path to read from.
206 * @return the de-serialized object.
207 * @throws NullPointerException if the input stream {@code in} is {@code null}.
208 * @throws IOException if the object could not be read.
209 */
210 public Object read(final String path) throws IOException {
211 return read(Object.class, path);
212 }
213
214 /**
215 * Reads an object from the given file.
216 *
217 * @param path the path to read from.
218 * @param type the type of the read object.
219 * @return the de-serialized object.
220 * @throws NullPointerException if the input stream {@code in} is {@code null}.
221 * @throws IOException if the object could not be read.
222 */
223 public <T> T read(final Class<T> type, final Path path)
224 throws IOException
225 {
226 try (final FileInputStream in = new FileInputStream(path.toFile())) {
227 return read(type, in);
228 }
229 }
230
231 /**
232 * Reads an object from the given file.
233 *
234 * @param path the path to read from.
235 * @return the de-serialized object.
236 * @throws NullPointerException if the input stream {@code in} is {@code null}.
237 * @throws IOException if the object could not be read.
238 */
239 public Object read(final Path path) throws IOException {
240 return read(Object.class, path);
241 }
242
243 /**
244 * Reads an object from the given file.
245 *
246 * @param file the file to read from.
247 * @param type the type of the read object.
248 * @return the de-serialized object.
249 * @throws NullPointerException if the input stream {@code in} is {@code null}.
250 * @throws IOException if the object could not be read.
251 */
252 public <T> T read(final Class<T> type, final File file)
253 throws IOException
254 {
255 try (final FileInputStream in = new FileInputStream(file)) {
256 return read(type, in);
257 }
258 }
259
260 /**
261 * Reads an object from the given file.
262 *
263 * @param file the file to read from.
264 * @return the de-serialized object.
265 * @throws NullPointerException if the input stream {@code in} is {@code null}.
266 * @throws IOException if the object could not be read.
267 */
268 public Object read(final File file) throws IOException {
269 return read(Object.class, file);
270 }
271
272 /**
273 * Reads an object from the given input stream.
274 *
275 * @param in the input stream to read from.
276 * @param type the type of the read object.
277 * @return the de-serialized object.
278 * @throws NullPointerException if the input stream {@code in} is {@code null}.
279 * @throws IOException if the object could not be read.
280 */
281 public abstract <T> T read(final Class<T> type, final InputStream in)
282 throws IOException;
283
284 /**
285 * Reads an object from the given input stream.
286 *
287 * @param in the input stream to read from.
288 * @return the de-serialized object.
289 * @throws NullPointerException if the input stream {@code in} is {@code null}.
290 * @throws IOException if the object could not be read.
291 */
292 public Object read(final InputStream in) throws IOException {
293 return read(Object.class, in);
294 }
295
296
297 /**
298 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
299 * @version 1.0 — <em>$Date: 2013-12-08 $</em>
300 */
301 private static final class NonClosableOutputStream extends OutputStream {
302 private final OutputStream _adoptee;
303
304 public NonClosableOutputStream(final OutputStream adoptee) {
305 _adoptee = adoptee;
306 }
307
308 @Override
309 public void close() throws IOException {
310 //Ignore close call.
311 _adoptee.flush();
312 }
313
314 @Override
315 public boolean equals(final Object obj) {
316 return _adoptee.equals(obj);
317 }
318
319 @Override
320 public void flush() throws IOException {
321 _adoptee.flush();
322 }
323
324 @Override
325 public int hashCode() {
326 return _adoptee.hashCode();
327 }
328
329 @Override
330 public String toString() {
331 return _adoptee.toString();
332 }
333
334 @Override
335 public void write(byte[] b, int off, int len) throws IOException {
336 _adoptee.write(b, off, len);
337 }
338
339 @Override
340 public void write(byte[] b) throws IOException {
341 _adoptee.write(b);
342 }
343
344 @Override
345 public void write(int b) throws IOException {
346 _adoptee.write(b);
347 }
348
349 }
350
351 /**
352 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
353 * @version 1.0 — <em>$Date: 2013-12-08 $</em>
354 */
355 private static final class NonClosableInputStream extends InputStream {
356 private final InputStream _adoptee;
357
358 public NonClosableInputStream(final InputStream adoptee) {
359 _adoptee = adoptee;
360 }
361
362 @Override
363 public int available() throws IOException {
364 return _adoptee.available();
365 }
366
367 @Override
368 public void close() throws IOException {
369 }
370
371 @Override
372 public void mark(int readlimit) {
373 _adoptee.mark(readlimit);
374 }
375
376 @Override
377 public boolean markSupported() {
378 return _adoptee.markSupported();
379 }
380
381 @Override
382 public int read() throws IOException {
383 return _adoptee.read();
384 }
385
386 @Override
387 public int read(byte[] b, int off, int len) throws IOException {
388 return _adoptee.read(b, off, len);
389 }
390
391 @Override
392 public int read(byte[] b) throws IOException {
393 return _adoptee.read(b);
394 }
395
396 @Override
397 public void reset() throws IOException {
398 _adoptee.reset();
399 }
400
401 @Override
402 public long skip(long n) throws IOException {
403 return _adoptee.skip(n);
404 }
405 }
406
407 }
|