org.openimaj.io.IOUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Core library functionality concerned with general programming problems
rather than multimedia specific functionality. Includes I/O utilities,
randomisation, hashing and type conversion.
The newest version!
/**
* Copyright (c) 2011, The University of Southampton and the individual contributors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the University of Southampton nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.openimaj.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Scanner;
import org.objenesis.strategy.StdInstantiatorStrategy;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* Methods for reading Readable objects and writing Writeable objects.
*
* @author Jonathon Hare ([email protected])
* @author Sina Samangooei ([email protected])
*/
public class IOUtils {
/**
* Create a new instance of the given class. The class must have a no-args
* constructor. The constructor doesn't have to be public.
*
* @param
* The type of object.
* @param cls
* The class.
* @return a new instance.
*/
public static T newInstance(Class cls) {
try {
return cls.newInstance();
} catch (final Exception e) {
try {
final Constructor constr = cls.getDeclaredConstructor();
if (constr != null) {
constr.setAccessible(true);
return constr.newInstance();
}
} catch (final Exception e1) {
throw new RuntimeException(e);
}
throw new RuntimeException(e);
}
}
/**
* Create a new instance of the given class. The class must have a no-args
* constructor. The constructor doesn't have to be public.
*
* @param
* The type of object.
* @param className
* The class name.
* @return a new instance.
*/
@SuppressWarnings("unchecked")
public static T newInstance(String className) {
try {
return newInstance(((Class) Class.forName(className)));
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
/**
* Read an object from a file.
*
* @param
* instance type expected
* @param f
* the file
* @return object read from file
* @throws IOException
* problem reading file
*/
@SuppressWarnings("unchecked")
public static T read(File f) throws IOException {
final ObjectWrapper ow = IOUtils.read(f, ObjectWrapper.class);
return (T) ow.object;
}
/**
* Read an object from a file.
*
* @param
* instance type expected
* @param f
* the file
* @param charset
* the charsetName sent to the reader which reads the file IFF
* the file is not binary
* @return object read from file
* @throws IOException
* problem reading file
*/
@SuppressWarnings("unchecked")
public static T read(File f, String charset) throws IOException {
final ObjectWrapper ow = IOUtils.read(f, ObjectWrapper.class, charset);
return (T) ow.object;
}
/**
* Write an object to a file fully. The object will be saved with class
* information so that it can be automatically re-instantiated using
* {@link #read(File)} without needing to know the actual type.
*
* @param
* instance type expected
* @param f
* the file
* @param object
* the object to write
* @throws IOException
* problem reading file
*/
public static void writeBinaryFull(File f, T object) throws IOException {
IOUtils.writeBinary(f, new ObjectWrapper(object));
}
/**
* Write an object to a file fully. The object will be saved with class
* information so that it can be automatically re-instantiated using
* {@link #read(File)} without needing to know the actual type.
*
* @param
* instance type expected
* @param f
* the file
* @param object
* the object to write
* @throws IOException
* problem reading file
*/
public static void writeASCIIFull(File f, T object) throws IOException {
IOUtils.writeASCII(f, new ObjectWrapper(object));
}
/**
* Write an object to a file fully. The object will be saved with class
* information so that it can be automatically re-instantiated using
* {@link #read(File)} without needing to know the actual type.
*
* @param
* instance type expected
* @param f
* the file
* @param object
* the object to write
* @param charset
* the charsetName sent to the internal writer
* @throws IOException
* problem reading file
*/
public static void writeASCIIFull(File f, T object, String charset) throws IOException {
IOUtils.writeASCII(f, new ObjectWrapper(object), charset);
}
/**
* Read a new instance of type class from a file.
*
* @param
* instance type expected
* @param f
* the file
* @param cls
* the class
* @return new instance of class instantiated from the file
* @throws IOException
* problem reading file
*/
public static T read(File f, Class cls) throws IOException {
return read(f, newInstance(cls));
}
/**
* Read a new instance of type class from a file.
*
* @param
* instance type expected
* @param f
* the file
* @param cls
* the class
* @param charset
* the charsetName sent to the reader which reads the file IFF
* the file is not binary
* @return new instance of class instantiated from the file
* @throws IOException
* problem reading file
*/
public static T read(File f, Class cls, String charset) throws IOException {
return read(f, newInstance(cls), charset);
}
/**
* Read a new instance of type class from an input stream.
*
* @param
* instance type expected
* @param ios
* the input stream
* @param cls
* the class
* @return new instance of class instantiated from the stream
* @throws IOException
* problem reading stream
*/
public static T read(InputStream ios, Class cls) throws IOException {
return read(ios, newInstance(cls));
}
/**
* Read a new instance of type class from an input stream.
*
* @param
* instance type expected
* @param ios
* the input stream
* @param cls
* the class
* @param charset
* the charsetName sent to the internal inputstreamreader
* @return new instance of class instantiated from the stream
* @throws IOException
* problem reading stream
*/
public static T read(InputStream ios, Class cls, String charset) throws IOException {
return read(ios, newInstance(cls), charset);
}
/**
* Open file input stream and call Readable#read(InputStream,T)
*
* @param
* instance type expected
* @param f
* the file
* @param obj
* the object of type T
* @return A new instance of type T
* @throws IOException
* an error reading the file
*/
public static T read(File f, T obj) throws IOException {
final FileInputStream fos = new FileInputStream(f);
try {
return read(fos, obj);
} finally {
if (fos != null)
fos.close();
}
}
/**
* Open file input stream and call Readable#read(InputStream,T)
*
* @param
* instance type expected
* @param f
* the file
* @param obj
* the object of type T
* @param charset
* the charsetName sent to the reader which reads the file IFF
* the file is not binary
* @return A new instance of type T
* @throws IOException
* an error reading the file
*/
public static T read(File f, T obj, String charset) throws IOException {
final FileInputStream fos = new FileInputStream(f);
try {
return read(fos, obj, charset);
} finally {
if (fos != null)
fos.close();
}
}
/**
* Read an instance of an object from an input stream. The stream is tested
* to contain the ASCII or binary header and the appropriate read instance
* is called.
*
* @see Readable#binaryHeader
* @see Readable#readBinary
* @see Readable#readASCII
* @param
* instance type expected
* @param fis
* the input stream
* @param obj
* the object to instantiate
* @return the object
*
* @throws IOException
* if there is a problem reading the stream from the file
*/
public static T read(InputStream fis, T obj) throws IOException {
final BufferedInputStream bis = new BufferedInputStream(fis);
if (obj instanceof ReadableBinary && isBinary(bis, ((ReadableBinary) obj).binaryHeader())) {
final byte[] header = new byte[((ReadableBinary) obj).binaryHeader().length];
bis.read(header, 0, header.length);
((ReadableBinary) obj).readBinary(new DataInputStream(bis));
return obj;
} else {
final BufferedReader br = new BufferedReader(new InputStreamReader(bis));
final char[] holder = new char[((ReadableASCII) obj).asciiHeader().length()];
br.read(holder);
((ReadableASCII) obj).readASCII(new Scanner(br));
return obj;
}
}
/**
* Read an instance of an object from an input stream. The stream is tested
* to contain the ASCII or binary header and the appropriate read instance
* is called.
*
* @see Readable#binaryHeader
* @see Readable#readBinary
* @see Readable#readASCII
* @param
* instance type expected
* @param fis
* the input stream
* @param obj
* the object to instantiate
* @param charset
* the charsetName sent the to the inputstreamreader
* @return the object
*
* @throws IOException
* if there is a problem reading the stream from the file
*/
public static T read(InputStream fis, T obj, String charset) throws IOException {
final BufferedInputStream bis = new BufferedInputStream(fis);
if (obj instanceof ReadableBinary && isBinary(bis, ((ReadableBinary) obj).binaryHeader())) {
final byte[] header = new byte[((ReadableBinary) obj).binaryHeader().length];
bis.read(header, 0, header.length);
((ReadableBinary) obj).readBinary(new DataInputStream(bis));
return obj;
} else {
final BufferedReader br = new BufferedReader(new InputStreamReader(bis, charset));
final char[] holder = new char[((ReadableASCII) obj).asciiHeader().length()];
br.read(holder);
((ReadableASCII) obj).readASCII(new Scanner(br));
return obj;
}
}
/**
* Read an instance of an object from a reader. The stream is assumed to be
* ascii and the appropriate read instance is called.
*
* @see Readable#readASCII
* @param
* instance type expected
* @param fis
* the input stream
* @param obj
* the object to instantiate
* @return the object
*
* @throws IOException
* if there is a problem reading the stream from the file
*/
public static T read(Reader fis, T obj) throws IOException {
final BufferedReader br = new BufferedReader(fis);
final char[] holder = new char[((ReadableASCII) obj).asciiHeader().length()];
br.read(holder);
((ReadableASCII) obj).readASCII(new Scanner(br));
return obj;
}
/**
* Read an instance of an object from a reader. The stream is assumed to be
* ascii and the appropriate read instance is called.
*
* @see Readable#readASCII
* @param
* instance type expected
* @param fis
* the input stream
* @param cls
* the object to instantiate
* @return the object
*
* @throws IOException
* if there is a problem reading the stream from the file
*/
public static T read(Reader fis, Class cls) throws IOException {
return read(fis, newInstance(cls));
}
/**
* Opens an input stream and calls input stream version
*
* @see IOUtils#isBinary(BufferedInputStream,byte[])
*
* @param f
* file containing data
* @param header
* expected header in binary format
* @return is the file in the binary format
* @throws IOException
* if there was a problem reading the input stream
*/
public static boolean isBinary(File f, byte[] header) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(f);
bis = new BufferedInputStream(fis);
return isBinary(bis, header);
} finally {
if (fis != null)
try {
fis.close();
} catch (final IOException e) {
}
if (bis != null)
try {
bis.close();
} catch (final IOException e) {
}
}
}
/**
* Extracts the binary header from object and calls the byte[] version
*
* @see IOUtils#isBinary(BufferedInputStream,byte[])
*
* @param
* expected data type
* @param bis
* stream containing data
* @param obj
* instance of expected data type
* @return does the stream contain binary information
* @throws IOException
* problem reading input stream
*/
public static boolean isBinary(BufferedInputStream bis, T obj) throws IOException {
return isBinary(bis, obj.binaryHeader());
}
/**
* Checks whether a given input stream contains readable binary information
* by checking for the first header.length bytes == header. The stream is
* reset to the beginning of the header once checked.
*
* @param bis
* stream containing data
* @param header
* expected binary header
* @return does the stream contain binary information
* @throws IOException
* problem reading or reseting the stream
*/
public static boolean isBinary(BufferedInputStream bis, byte[] header) throws IOException {
bis.mark(header.length + 10);
final byte[] aheader = new byte[header.length];
bis.read(aheader, 0, aheader.length);
bis.reset();
return Arrays.equals(aheader, header);
}
/**
* Write a Writeable T object instance. Opens a file stream and calls output
* stream version
*
* @see IOUtils#writeBinary(OutputStream,Writeable)
*
* @param
* data type to be written
* @param f
* file to write instance to
* @param obj
* instance to be written
* @throws IOException
* error reading file
*/
public static void writeBinary(File f, T obj) throws IOException {
final FileOutputStream fos = new FileOutputStream(f);
try {
writeBinary(fos, obj);
fos.flush();
} finally {
if (fos != null)
fos.close();
}
}
/**
* Write a Writeable T object instance to the provided output stream, calls
* BufferedOutputStream version
*
* @see IOUtils#writeBinary(BufferedOutputStream,Writeable)
*
* @param
* Expected data type
* @param fos
* output stream
* @param obj
* the object to write
* @throws IOException
* error writing to stream
*/
public static void writeBinary(OutputStream fos, T obj) throws IOException {
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(fos);
writeBinary(bos, obj);
} finally {
if (bos != null) {
bos.flush();
}
}
}
/**
* Writeable object is written to the output stream in binary format.
* Firstly the binaryHeader is written then the object is handed the output
* stream to write it's content.
*
* @see Writeable#writeBinary(java.io.DataOutput)
* @see Writeable#binaryHeader()
*
* @param
* instance type expected
* @param bos
* the output stream
* @param obj
* the object to write
* @throws IOException
* error writing to stream
*/
public static void writeBinary(BufferedOutputStream bos, T obj) throws IOException {
final DataOutputStream dos = new DataOutputStream(bos);
dos.write(obj.binaryHeader());
obj.writeBinary(dos);
}
/**
* Writeable object is written to the a file in ASCII format. File stream is
* opened and stream version is called
*
* @see IOUtils#writeASCII(OutputStream, Writeable)
*
* @param
* instance type expected
* @param f
* the file to write to
* @param obj
* the object to write
* @throws IOException
* error writing to file
*/
public static void writeASCII(File f, T obj) throws IOException {
final FileOutputStream fos = new FileOutputStream(f);
try {
writeASCII(fos, obj);
fos.flush();
} finally {
if (fos != null)
fos.close();
}
}
/**
* Writeable object is written to the a file in ASCII format. File stream is
* opened and stream version is called
*
* @see IOUtils#writeASCII(OutputStream, Writeable)
*
* @param
* instance type expected
* @param f
* the file to write to
* @param obj
* the object to write
* @param charset
* the charsetName sent to the internal writer
* @throws IOException
* error writing to file
*/
public static void writeASCII(File f, T obj, String charset) throws IOException {
final FileOutputStream fos = new FileOutputStream(f);
try {
writeASCII(fos, obj, charset);
fos.flush();
} finally {
if (fos != null)
fos.close();
}
}
/**
* Write the object in ASCII format to the output stream. Construct a
* PrintWriter using the outputstream, write the object's ASCII header then
* write the object in ASCII format.
*
* @see PrintWriter
* @see Writeable#asciiHeader()
* @see Writeable#writeASCII(PrintWriter)
*
* @param
* instance type expected
* @param fos
* the output stream
* @param obj
* the object
* @throws IOException
* error writing to stream
*/
public static void writeASCII(OutputStream fos, T obj) throws IOException {
PrintWriter pw = null;
try {
pw = new PrintWriter(fos);
pw.print(obj.asciiHeader());
obj.writeASCII(pw);
} finally {
if (pw != null) {
pw.flush();
}
}
}
/**
* Write the object in ASCII format to the output stream. Construct a
* PrintWriter using the outputstream, write the object's ASCII header then
* write the object in ASCII format.
*
* @see PrintWriter
* @see Writeable#asciiHeader()
* @see Writeable#writeASCII(PrintWriter)
*
* @param
* instance type expected
* @param fos
* the output stream
* @param obj
* the object
* @param charset
* the charsetName sent to the internal outputstreamwriter
* @throws IOException
* error writing to stream
*/
public static void writeASCII(OutputStream fos, T obj, String charset) throws IOException {
PrintWriter pw = null;
try {
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, charset)));
pw.print(obj.asciiHeader());
obj.writeASCII(pw);
} finally {
if (pw != null) {
pw.flush();
}
}
}
/**
* Write the object in ASCII format to the output stream. Construct a
* PrintWriter using the outputstream, write the object's ASCII header then
* write the object in ASCII format.
*
* @see PrintWriter
* @see Writeable#asciiHeader()
* @see Writeable#writeASCII(PrintWriter)
*
* @param
* instance type expected
* @param writer
* the output stream
* @param obj
* the object
* @throws IOException
* error writing to stream
*/
public static void writeASCII(Writer writer, T obj) throws IOException {
PrintWriter pw = null;
try {
pw = new PrintWriter(writer);
pw.print(obj.asciiHeader());
obj.writeASCII(pw);
} finally {
if (pw != null) {
pw.flush();
}
}
}
/**
* Check whether a given file is readable by a given Writeable class.
* Instantiates the class to get it's binary and ascii header which is then
* passed to the byte[] version of this method
*
* @see Readable#asciiHeader()
*
* @param
* instance type expected
* @param f
* the file to check
* @param cls
* the class to instantiate the Readable object
* @return is file readable by a given class
* @throws IOException
* error reading file
*/
public static boolean readable(File f, Class cls) throws IOException {
final InternalReadable obj = newInstance(cls);
return (obj instanceof ReadableBinary && readable(f, ((ReadableBinary) obj).binaryHeader())) ||
(obj instanceof ReadableASCII && readable(f, ((ReadableASCII) obj).asciiHeader()));
}
/**
* Check whether a file is readable by checking it's first bytes contains
* the header. Converts the header to a byte[] and calls the byte[] version
* of this method
*
* @see IOUtils#readable(File, byte[])
*
* @param f
* the file to check
* @param header
* the header to check with
* @return does this file contain this header
* @throws IOException
* error reading file
*/
public static boolean readable(File f, String header) throws IOException {
return readable(f, header.getBytes());
}
/**
* Check readability by checking whether a file starts with a given header.
* Instantiate an input stream and check whether the stream isBinary (i.e.
* starts with the header)
*
* @see IOUtils#isBinary(BufferedInputStream, byte[])
*
* @param f
* file to check
* @param header
* the expected header
* @return does the file start with the header
* @throws IOException
* error reading file
*/
public static boolean readable(File f, byte[] header) throws IOException {
FileInputStream fos = null;
try {
fos = new FileInputStream(f);
final BufferedInputStream bis = new BufferedInputStream(fos);
return isBinary(bis, header);
} finally {
try {
if (fos != null)
fos.close();
} catch (final IOException e) {
}
}
}
/**
* Check whether an InputStream can be read by an instantiated class based
* on it's binary and ascii headers. Buffered so the stream can be reset
* after the check.
*
* @param
* instance type expected
* @param bis
* the stream
* @param cls
* the class to instantiate and check
* @return can an object be read from this stream of the class type
* @throws IOException
* error reading stream
*/
public static boolean readable(BufferedInputStream bis, Class cls) throws IOException
{
final InternalReadable obj = newInstance(cls);
return (obj instanceof ReadableBinary && readable(bis, ((ReadableBinary) obj).binaryHeader())) ||
(obj instanceof ReadableASCII && readable(bis, ((ReadableASCII) obj).asciiHeader()));
}
/**
* Check whether an input stream starts with a header string. Calls the
* byte[] version of this function
*
* @see IOUtils#isBinary(BufferedInputStream, byte[])
*
* @param bis
* the input stream
* @param header
* the header
* @return whether the stream starts with the string
* @throws IOException
* error reading stream
*/
public static boolean readable(BufferedInputStream bis, String header) throws IOException {
return readable(bis, header.getBytes());
}
/**
* Check whether a stream starts with a header. Uses isBinary (therefore
* resetting the stream after the check)
*
* @param bis
* the input stream
* @param header
* the byte[] header
* @return whether the stream starts with the header
* @throws IOException
* error reading stream
*/
public static boolean readable(BufferedInputStream bis, byte[] header) throws IOException {
return isBinary(bis, header);
}
/**
* Convenience function for serializing a writeable object as a byte array.
* Calls {@link IOUtils#writeBinary(OutputStream, WriteableBinary)} on a
* {@link ByteArrayOutputStream} then calls
* {@link ByteArrayOutputStream#toByteArray()}
*
* @param object
* @return serialised object
* @throws IOException
*/
public static byte[] serialize(WriteableBinary object) throws IOException {
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
IOUtils.writeBinary(stream, object);
return stream.toByteArray();
}
/**
* Convenience function for deserializing an object from a String. Calls
* {@link ReadableASCII#readASCII(Scanner)} with a Scanner initialized from
* a StringReader
*
* @param source
* where to read from
* @param clazz
* the class of the output
* @param
* the type to output
* @return a new instance of T
* @throws IOException
*/
public static T fromString(String source, Class clazz) throws IOException {
final T out = IOUtils.read(new ByteArrayInputStream(source.getBytes()), clazz);
return out;
}
/**
* Convenience function for deserializing an object from a byte array. Calls
* {@link IOUtils#read(InputStream, Class)} on a
* {@link ByteArrayInputStream}.
*
* @param source
* where to read from
* @param clazz
* the class of the output
* @param
* the type to output
* @return a new instance of T
* @throws IOException
*/
public static T deserialize(byte[] source, Class clazz) throws IOException {
final ByteArrayInputStream stream = new ByteArrayInputStream(source);
final T out = IOUtils.read(stream, clazz);
return out;
}
/**
* Convenience function for deserializing an object from a byte array. Calls
* {@link IOUtils#read(InputStream, Class)} on a
* {@link ByteArrayInputStream}.
*
* @param source
* where to read from
* @param clazz
* the class of the output
* @param
* the type to output
* @param skip
* number of bytes to skip
* @return a new instance of T
* @throws IOException
*/
public static T deserialize(byte[] source, long skip, Class clazz) throws IOException {
final ByteArrayInputStream stream = new ByteArrayInputStream(source);
stream.skip(skip);
final T out = IOUtils.read(stream, clazz);
return out;
}
/**
* Convenience function for deserializing an object from a byte array. Calls
* {@link IOUtils#read(InputStream, Class)} on a
* {@link ByteArrayInputStream}.
*
* @param source
* where to read from
* @param instance
* a T instance
* @param
* the type to output
* @return a new instance of T
* @throws IOException
*/
public static T deserialize(byte[] source, T instance) throws IOException {
final ByteArrayInputStream stream = new ByteArrayInputStream(source);
final T out = IOUtils.read(stream, instance);
return out;
}
/**
* Writes an object to a file using the Kryo serialisation library. The
* object doesn't need to have any special serialisation attributes.
*
* @param obj
* the object to write
* @param out
* the output sink
* @throws IOException
*/
public static void writeToFile(Object obj, File out) throws IOException {
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new FileOutputStream(out));
write(obj, dos);
} finally {
if (dos != null)
try {
dos.close();
} catch (final IOException e) {
}
}
}
/**
* Writes an object using the Kryo serialisation library. The object doesn't
* need to have any special serialisation attributes.
*
* @param obj
* the object to write
* @param out
* the output sink
* @throws IOException
*/
public static void write(Object obj, DataOutput out) throws IOException {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final Output output = new Output(bos);
final Kryo kryo = new Kryo();
kryo.writeClassAndObject(output, obj);
output.flush();
final byte[] array = bos.toByteArray();
out.writeInt(array.length);
out.write(array);
}
/**
* Utility method to read any object written with
* {@link #write(Object, DataOutput)}.
*
* @param
* type of object
* @param in
* input
* @return the object
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static T read(DataInput in) throws IOException {
final int length = in.readInt();
final byte[] bytes = new byte[length];
in.readFully(bytes);
final Kryo kryo = new Kryo();
Object obj;
try {
obj = kryo.readClassAndObject(new Input(bytes));
} catch (final KryoException e) {
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
obj = kryo.readClassAndObject(new Input(bytes));
}
return (T) obj;
}
/**
* Utility method to read any object written with
* {@link #writeToFile(Object, File)}.
*
* @param
* type of object
* @param in
* input file
* @return the object
* @throws IOException
*/
public static T readFromFile(File in) throws IOException {
DataInputStream din = null;
try {
din = new DataInputStream(new FileInputStream(in));
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
return IOUtils. read(din);
} finally {
if (din != null)
try {
din.close();
} catch (final IOException e) {
}
}
}
/**
* Test whether the data in the given {@link InputStream} can be read by the
* given {@link InputStreamObjectReader}. This method tries to ensure that
* the stream is reset to its initial condition.
*
* @param reader
* the {@link InputStreamObjectReader}.
* @param is
* the stream
* @param name
* the name of the file/object behind the stream (can be null)
* @return true if the {@link InputStreamObjectReader} can read from this
* stream; false otherwise.
* @throws IOException
* if an error occurs resetting the stream.
*/
public static boolean canRead(InputStreamObjectReader> reader, BufferedInputStream is, String name)
throws IOException
{
try {
is.mark(1024 * 1024);
return reader.canRead(is, name);
} finally {
is.reset();
}
}
/**
* Test whether the data in the given source can be read by the given
* {@link ObjectReader}.
*
* @param reader
* the {@link ObjectReader}.
* @param source
* the source
* @param name
* the name of the file/object behind the stream (can be null)
* @return true if the {@link ObjectReader} can read from this stream; false
* otherwise.
* @throws IOException
* if an error occurs resetting the stream.
*/
public static boolean canRead(ObjectReader, SRC> reader, SRC source, String name) throws IOException {
return reader.canRead(source, name);
}
}