001/* 002 * Java Genetic Algorithm Library (jenetics-8.3.0). 003 * Copyright (c) 2007-2025 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 * @SuppressWarnings("unchecked) 049 * ISeq<Phenotype<G, C>> population = (ISeq<Phenotype<G, C>>)IO.object.read(file); 050 * EvolutionStream<DoubleGene, Double> stream = Engine 051 * .build(ff, gtf) 052 * .stream(population, 1); 053 * } 054 * 055 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 056 * @since 1.0 057 * @version 4.0 058 */ 059public abstract class IO { 060 061 protected IO() { 062 } 063 064 /** 065 * IO implementation for "native" <i>Java</i> serialization. 066 */ 067 public static final IO object = new IO() { 068 069 @Override 070 public void write(final Object object, final OutputStream out) 071 throws IOException 072 { 073 final ObjectOutputStream oout = new ObjectOutputStream(out); 074 oout.writeObject(object); 075 oout.flush(); 076 } 077 078 @Override 079 public <T> T read(final Class<T> type, final InputStream in) 080 throws IOException 081 { 082 final ObjectInputStream oin = new ObjectInputStream(in); 083 try { 084 return type.cast(oin.readObject()); 085 } catch (ClassNotFoundException | ClassCastException e) { 086 throw new IOException(e); 087 } 088 } 089 }; 090 091 /** 092 * Serializes the given {@code object} to a {@code byte[]} array. 093 * 094 * @since 4.1 095 * 096 * @param object the object to serialize. 097 * @throws NullPointerException if one of the objects is {@code null}. 098 * @throws IOException if the object could not be serialized. 099 * @return the serialized {@code object} as {@code byte[]} array 100 */ 101 public byte[] toByteArray(final Object object) throws IOException { 102 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 103 write(object, out); 104 return out.toByteArray(); 105 } 106 107 /** 108 * Write the (serializable) object to the given path. 109 * 110 * @param object the object to serialize. 111 * @param path the path to write the object to. 112 * @throws NullPointerException if one of the arguments is {@code null}. 113 * @throws IOException if the object could not be serialized. 114 */ 115 public void write(final Object object, final String path) 116 throws IOException 117 { 118 write(object, new File(path)); 119 } 120 121 /** 122 * Write the (serializable) object to the given path. 123 * 124 * @param object the object to serialize. 125 * @param path the path to write the object to. 126 * @throws NullPointerException if one of the arguments is {@code null}. 127 * @throws IOException if the object could not be serialized. 128 */ 129 public void write(final Object object, final Path path) 130 throws IOException 131 { 132 write(object, path.toFile()); 133 } 134 135 /** 136 * Write the (serializable) object to the given file. 137 * 138 * @param object the object to serialize. 139 * @param file the file to write the object to. 140 * @throws NullPointerException if one of the arguments is {@code null}. 141 * @throws IOException if the object could not be serialized. 142 */ 143 public void write(final Object object, final File file) 144 throws IOException 145 { 146 try (final FileOutputStream out = new FileOutputStream(file)) { 147 write(object, out); 148 } 149 } 150 151 /** 152 * Write the (serializable) object to the given output stream. 153 * 154 * @param object the object to serialize. 155 * @param out the output stream to write the object to. 156 * @throws NullPointerException if one of the arguments is {@code null}. 157 * @throws IOException if the object could not be serialized. 158 */ 159 public abstract void write(final Object object, final OutputStream out) 160 throws IOException; 161 162 /** 163 * Creates a previously serialized, object from the given {@code byte[]} 164 * array. 165 * 166 * @since 4.1 167 * 168 * @param bytes the serialized object. 169 * @return the deserialized object. 170 * @throws NullPointerException if the input {@code bytes} is {@code null}. 171 * @throws IOException if the object could not be deserialized. 172 */ 173 public Object fromByteArray(final byte[] bytes) throws IOException { 174 final ByteArrayInputStream in = new ByteArrayInputStream(bytes); 175 return read(in); 176 } 177 178 /** 179 * Reads an object from the given file. 180 * 181 * @param <T> the type of the read object 182 * @param path the path to read from. 183 * @param type the type of the read object. 184 * @return the deserialized object. 185 * @throws NullPointerException if the input stream {@code in} is {@code null}. 186 * @throws IOException if the object could not be read. 187 */ 188 public <T> T read(final Class<T> type, final String path) 189 throws IOException 190 { 191 try (final FileInputStream in = new FileInputStream(new File(path))) { 192 return read(type, in); 193 } 194 } 195 196 /** 197 * Reads an object from the given file. 198 * 199 * @param path the path to read from. 200 * @return the deserialized object. 201 * @throws NullPointerException if the input stream {@code in} is {@code null}. 202 * @throws IOException if the object could not be read. 203 */ 204 public Object read(final String path) throws IOException { 205 return read(Object.class, path); 206 } 207 208 /** 209 * Reads an object from the given file. 210 * 211 * @param <T> the type of the read object 212 * @param path the path to read from. 213 * @param type the type of the read object. 214 * @return the deserialized object. 215 * @throws NullPointerException if the input stream {@code in} is {@code null}. 216 * @throws IOException if the object could not be read. 217 */ 218 public <T> T read(final Class<T> type, final Path path) 219 throws IOException 220 { 221 try (final FileInputStream in = new FileInputStream(path.toFile())) { 222 return read(type, in); 223 } 224 } 225 226 /** 227 * Reads an object from the given file. 228 * 229 * @param path the path to read from. 230 * @return the deserialized object. 231 * @throws NullPointerException if the input stream {@code in} is {@code null}. 232 * @throws IOException if the object could not be read. 233 */ 234 public Object read(final Path path) throws IOException { 235 return read(Object.class, path); 236 } 237 238 /** 239 * Reads an object from the given file. 240 * 241 * @param <T> the type of the read object 242 * @param file the file to read from. 243 * @param type the type of the read object. 244 * @return the deserialized object. 245 * @throws NullPointerException if the input stream {@code in} is {@code null}. 246 * @throws IOException if the object could not be read. 247 */ 248 public <T> T read(final Class<T> type, final File file) 249 throws IOException 250 { 251 try (final FileInputStream in = new FileInputStream(file)) { 252 return read(type, in); 253 } 254 } 255 256 /** 257 * Reads an object from the given file. 258 * 259 * @param file the file to read from. 260 * @return the deserialized object. 261 * @throws NullPointerException if the input stream {@code in} is {@code null}. 262 * @throws IOException if the object could not be read. 263 */ 264 public Object read(final File file) throws IOException { 265 return read(Object.class, file); 266 } 267 268 /** 269 * Reads an object from the given input stream. 270 * 271 * @param <T> the type of the read object 272 * @param in the input stream to read from. 273 * @param type the type of the read object. 274 * @return the deserialized object. 275 * @throws NullPointerException if the input stream {@code in} is {@code null}. 276 * @throws IOException if the object could not be read. 277 */ 278 public abstract <T> T read(final Class<T> type, final InputStream in) 279 throws IOException; 280 281 /** 282 * Reads an object from the given input stream. 283 * 284 * @param in the input stream to read from. 285 * @return the deserialized object. 286 * @throws NullPointerException if the input stream {@code in} is {@code null}. 287 * @throws IOException if the object could not be read. 288 */ 289 public Object read(final InputStream in) throws IOException { 290 return read(Object.class, in); 291 } 292}