/* Copyright (c) 2009-2011 Speech Group at Informatik 5, Univ. Erlangen-Nuremberg, GERMANY Korbinian Riedhammer Tobias Bocklet This file is part of the Java Speech Toolkit (JSTK). The JSTK is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The JSTK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the JSTK. If not, see <http://www.gnu.org/licenses/>. */ package de.fau.cs.jstk.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; /** * Use the IOUtil methods to simplify the binary input/output handling of * byte, int, short, float and double values and arrays * * @author sikoried */ public final class IOUtil { /** * Read a single byte from the InputStream * @param is * @return * @throws IOException */ public static byte readByte(InputStream is) throws IOException { byte [] buf = new byte[1]; if (is.read(buf) != 1) throw new IOException("could not read requested byte"); return buf[0]; } /** * Read a byte array from the InputStream * @param is * @param buf * @return false if the buffer could not be filled * @throws IOException */ public static boolean readByte(InputStream is, byte [] buf) throws IOException { int read = is.read(buf); return read == buf.length; } /** * Read len bytes from the InputStream * @param is * @param buf * @param len * @return false if less bytes read than requested * @throws IOException */ public static boolean readByte(InputStream is, byte [] buf, int len) throws IOException { int read = is.read(buf, 0, len); return read == len; } /** * Write a single byte to the OutputStream * @param os * @param b * @throws IOException */ public static void writeByte(OutputStream os, byte b) throws IOException { os.write(new byte [] { b }); } /** * Write a byte array to the OutputStream * @param os * @param buf * @throws IOException */ public static void writeByte(OutputStream os, byte [] buf) throws IOException { os.write(buf); } /** * Write len bytes to the OutputStream * @param os * @param buf * @param len * @throws IOException */ public static void writeByte(OutputStream os, byte [] buf, int len) throws IOException { os.write(buf, 0, len); } /** * Read a single short value from the given InputStream using given ByteOrder * @param is * @param bo * @return * @throws IOException */ public static short readShort(InputStream is, ByteOrder bo) throws IOException { byte [] bbuf = new byte [Short.SIZE / 8]; int read = is.read(bbuf); // complete frame? if (read < bbuf.length) throw new IOException ("could not read required bytes"); // decode the double ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); return bb.getShort(); } /** * Read an array of shorts from the given InputStream using given ByteOrder * @param is * @param buf * @param bo * @return false if buffer could not be filled * @throws IOException */ public static boolean readShort(InputStream is, short [] buf, ByteOrder bo) throws IOException { byte [] bbuf = new byte [buf.length * Short.SIZE / 8]; int read = is.read(bbuf); // complete frame? if (read < bbuf.length) return false; // decode the short ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); for (int i = 0; i < buf.length; ++i) buf[i] = bb.getShort(); return true; } /** * Write a single short to the OutputStream * pointer respectively. * @param os * @param val * @param bo * @throws IOException */ public static void writeShort(OutputStream os, short val, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(Short.SIZE/8); bb.order(bo); bb.putShort(val); os.write(bb.array()); } /** * Write the given short array to the OutputStream using given ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeShort(OutputStream os, short [] buf, ByteOrder bo) throws IOException { writeShort(os, buf, buf.length, bo); } /** * Write the given short array to the OutputStream using given ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeShort(OutputStream os, short [] buf, int length, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(buf.length * Short.SIZE/8); bb.order(bo); for (int i = 0; i < length; ++i) bb.putShort(buf[i]); os.write(bb.array()); } /** * Read a single int from the InputStream using given ByteOrder * pointer respectively. * @param is * @param bo * @return * @throws IOException */ public static int readInt(InputStream is, ByteOrder bo) throws IOException { byte [] bbuf = new byte [Integer.SIZE / 8]; int read = is.read(bbuf); if (read < bbuf.length) throw new IOException ("could not read required bytes"); ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); return bb.getInt(); } /** * Read a single int from the InputStream using given ByteOrder * pointer respectively. * @param is * @param buf * @param bo * @return false if frame could not be filled * @throws IOException */ public static boolean readInt(InputStream is, int [] buf, ByteOrder bo) throws IOException { byte [] bbuf = new byte [buf.length * Integer.SIZE/8]; int read = is.read(bbuf); if (read < bbuf.length) return false; ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); for (int i = 0; i < buf.length; ++i) buf[i] = bb.getInt(); return true; } /** * Write an int to the OutputStream and advance the stream * pointer respectively. * @param os * @param val * @param bo * @return * @throws IOException */ public static void writeInt(OutputStream os, int val, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE/8); bb.order(bo); bb.putInt(val); os.write(bb.array()); } /** * Write the given int array to the OutputStream using given ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeInt(OutputStream os, int [] buf, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(buf.length * Integer.SIZE/8); bb.order(bo); for (int d : buf) bb.putInt(d); os.write(bb.array()); } /** * Read a single long from the InputStream using given ByteOrder * pointer respectively. * @param is * @param bo * @return * @throws IOException */ public static long readLong(InputStream is, ByteOrder bo) throws IOException { byte [] bbuf = new byte [Long.SIZE / 8]; int read = is.read(bbuf); if (read < bbuf.length) throw new IOException ("could not read required bytes"); ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); return bb.getLong(); } /** * Read a long array from the InputStream using given ByteOrder * pointer respectively. * @param is * @param buf * @param bo * @return false if frame could not be filled * @throws IOException */ public static boolean readLong(InputStream is, long [] buf, ByteOrder bo) throws IOException { byte [] bbuf = new byte [buf.length * Long.SIZE/8]; int read = is.read(bbuf); if (read < bbuf.length) return false; ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); for (int i = 0; i < buf.length; ++i) buf[i] = bb.getLong(); return true; } /** * Write an int to the OutputStream and advance the stream * pointer respectively. * @param os * @param val * @param bo * @return * @throws IOException */ public static void writeLong(OutputStream os, long val, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(Long.SIZE/8); bb.order(bo); bb.putLong(val); os.write(bb.array()); } /** * Write the given long array to the OutputStream using given ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeLong(OutputStream os, long [] buf, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(buf.length * Long.SIZE/8); bb.order(bo); for (long d : buf) bb.putLong(d); os.write(bb.array()); } /** * Read a single Float from the InputStream using given ByteOrder * @param is * @param bo * @return * @throws IOException */ public static float readFloat(InputStream is, ByteOrder bo) throws IOException { byte [] bbuf = new byte[Float.SIZE / 8]; int read = is.read(bbuf); // complete frame? if (read < bbuf.length) throw new IOException("could not read required bytes"); // decode the double ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); return bb.getFloat(); } /** * Reads float array from a InputStream using given ByteOrder * * @param is binary InputStream * @param buf (output) buffer * @return true on success, false else. * @throws IOException */ public static boolean readFloat(InputStream is, float [] buf, ByteOrder bo) throws IOException { byte [] bbuf = new byte[buf.length * Float.SIZE / 8]; int read = is.read(bbuf); // complete frame? if (read < bbuf.length) return false; // decode the double ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); for (int i = 0; i < buf.length; ++i) buf[i] = bb.getFloat(); return true; } /** * Reads floats from a binary InputStream and store them in the double buffer * using given ByteOrder * @param is binary InputStream * @param buf (output) buffer * @return true on success, false else. * @throws IOException */ public static boolean readFloat(InputStream is, double [] buf, ByteOrder bo) throws IOException { byte [] bbuf = new byte[buf.length * Float.SIZE / 8]; int read = is.read(bbuf); // complete frame? if (read < bbuf.length) return false; // decode the double ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); for (int i = 0; i < buf.length; ++i) buf[i] = bb.getFloat(); return true; } /** * Reads float array from ASCII stream * * @param br allocated BufferedReader * @param buf (output) buffer * @return true on success, false else. * @throws IOException */ public static boolean readFloat(BufferedReader br, float [] buf) throws IOException { String line = br.readLine(); if (line == null) return false; String [] tokens = line.trim().split("\\s+"); if (tokens.length != buf.length) return false; for (int i = 0; i < tokens.length; ++i) buf[i] = Float.valueOf(tokens[i]); return true; } /** * Read a float array from the stream without knowing its size ahead of time * @param br * @return float array */ public float [] readFloat(BufferedReader br) throws IOException { String line = br.readLine(); if (line == null) return null; String [] tokens = line.trim().split("\\s+"); float [] buf = new float [tokens.length]; for (int i = 0; i < tokens.length; ++i) buf[i] = Float.valueOf(tokens[i]); return buf; } /** * Write a float to the OutputStream * pointer respectively. * @param os * @param val * @param bo * @return * @throws IOException */ public static void writeFloat(OutputStream os, float val, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(Float.SIZE/8); bb.order(bo); bb.putFloat(val); os.write(bb.array()); } /** * Write the given float array to the OutputStream using the specified * ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeFloat(OutputStream os, float [] buf, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(buf.length * Float.SIZE/8); bb.order(bo); for (float f : buf) bb.putFloat(f); os.write(bb.array()); } /** * Write the given double array as floats to the OutputStream using the * specified ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeFloat(OutputStream os, double [] buf, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(buf.length * Float.SIZE/8); bb.order(bo); for (double d : buf) bb.putFloat((float) d); os.write(bb.array()); } /** * Write a given float array to the ASCII stream * @param bw * @param buf * @throws IOException */ public static void writeFloat(BufferedWriter bw, float [] buf) throws IOException { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length - 1; ++i) sb.append(Float.toString(buf[i]) + " "); sb.append(Float.toString(buf[buf.length-1]) + "\n"); bw.append(sb.toString()); } /** * Read a single Double from the InputStream * @param is * @param bo * @return * @throws IOException */ public static double readDouble(InputStream is, ByteOrder bo) throws IOException { byte [] bbuf = new byte[Double.SIZE / 8]; int read = is.read(bbuf); if (read < bbuf.length) throw new IOException("could not read required bytes"); ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); return bb.getDouble(); } /** * Reads double array from a binary InputStream * * @param is binary InputStream * @param buf (output) buffer * @return true on success, false else. * @throws IOException */ public static boolean readDouble(InputStream is, double [] buf, ByteOrder bo) throws IOException { byte [] bbuf = new byte[buf.length * Double.SIZE / 8]; int read = is.read(bbuf); if (read < bbuf.length) return false; ByteBuffer bb = ByteBuffer.wrap(bbuf); bb.order(bo); for (int i = 0; i < buf.length; ++i) buf[i] = bb.getDouble(); return true; } /** * Reads doubles from ASCII stream * * @param br allocated BufferedReader * @param buf (output) buffer * @return true on success, false else. * @throws IOException */ public static boolean readDouble(BufferedReader br, double [] buf) throws IOException { String line = br.readLine(); if (line == null) return false; String [] tokens = line.trim().split("\\s+"); if (tokens.length != buf.length) return false; for (int i = 0; i < tokens.length; ++i) buf[i] = Double.valueOf(tokens[i]); return true; } /** * Read a double array from the stream without knowing its size ahead of time * @param br * @return */ public double [] readDouble(BufferedReader br) throws IOException { String line = br.readLine(); if (line == null) return null; String [] tokens = line.trim().split("\\s+"); double [] buf = new double [tokens.length]; for (int i = 0; i < tokens.length; ++i) buf[i] = Double.valueOf(tokens[i]); return buf; } /** * Write a double to the OutputStream * pointer respectively. * @param os * @param val * @param bo * @return * @throws IOException */ public static void writeDouble(OutputStream os, double val, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(Double.SIZE/8); bb.order(bo); bb.putDouble(val); os.write(bb.array()); } /** * Write the given double array to the OutputStream using the specified * ByteOrder * @param os * @param buf * @param bo * @throws IOException */ public static void writeDouble(OutputStream os, double [] buf, ByteOrder bo) throws IOException { ByteBuffer bb = ByteBuffer.allocate(buf.length * Double.SIZE/8); bb.order(bo); for (double d : buf) bb.putDouble(d); os.write(bb.array()); } /** * Write a given double array to the ASCII stream * @param bw * @param buf * @throws IOException */ public static void writeDouble(BufferedWriter bw, double [] buf) throws IOException { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length - 1; ++i) sb.append(Double.toString(buf[i]) + " "); sb.append(Double.toString(buf[buf.length-1]) + "\n"); bw.append(sb.toString()); } }