001/* 002 * Java Genetic Algorithm Library (jenetics-8.1.0). 003 * Copyright (c) 2007-2024 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 */ 020package io.jenetics.util; 021 022import java.io.ByteArrayInputStream; 023import java.io.ByteArrayOutputStream; 024import java.io.File; 025import java.io.FileInputStream; 026import java.io.FileOutputStream; 027import java.io.IOException; 028import java.io.InputStream; 029import java.io.ObjectInputStream; 030import java.io.ObjectOutputStream; 031import java.io.OutputStream; 032import 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 * <p> 038 * {@snippet lang="java": 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 * } 053 * 054 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 055 * @since 1.0 056 * @version 4.0 057 */ 058public 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 objects 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 object) throws 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 deserialized object. 169 * @throws NullPointerException if the input {@code bytes} is {@code null}. 170 * @throws IOException if the object could not be deserialized. 171 */ 172 public Object fromByteArray(final byte[] bytes) throws 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 deserialized 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 deserialized 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 path) throws 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 deserialized 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 deserialized 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 path) throws 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 deserialized 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 deserialized 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 file) throws 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 deserialized 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 deserialized 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 in) throws IOException { 289 return read(Object.class, in); 290 } 291}