com.hfg.util.io.FileBytes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.util.io;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import com.hfg.exception.ProgrammingException;
import com.hfg.util.FileUtil;
import com.hfg.util.collection.CollectionUtil;
//------------------------------------------------------------------------------
/**
Container for a file name plus file contents as bytes.
Useful for holding temp files created in memory before producing a zip archive.
@author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class FileBytes
{
private String mName;
List mDataChunks;
private Long mLength;
//###########################################################################
// CONSTRUCTORS
//###########################################################################
//--------------------------------------------------------------------------
public FileBytes(String inName)
{
mName = inName;
}
//###########################################################################
// PUBLIC METHODS
//###########################################################################
//--------------------------------------------------------------------------
public String name()
{
return mName;
}
//--------------------------------------------------------------------------
public long length()
{
return mLength != null ? mLength : 0;
}
//--------------------------------------------------------------------------
public FileBytes setData(byte[] inData)
{
mDataChunks = new ArrayList<>(1);
mDataChunks.add(inData);
return this;
}
//--------------------------------------------------------------------------
public FileBytes setData(InputStream inStream)
throws IOException
{
BufferedInputStream bufferedStream = null;
try
{
bufferedStream = new BufferedInputStream(inStream);
mDataChunks = new ArrayList<>(50);
long length = 0;
byte[] transferBuffer = new byte[16 * 1024];
int readSize = 0;
while ((readSize = bufferedStream.read(transferBuffer)) >= 0)
{
mDataChunks.add(Arrays.copyOfRange(transferBuffer, 0, readSize));
length += readSize;
}
mLength = length;
}
finally
{
if (bufferedStream != null)
{
bufferedStream.close();
}
}
return this;
}
//--------------------------------------------------------------------------
public FileBytes appendData(byte[] inBytes)
throws IOException
{
if (null == mDataChunks)
{
mDataChunks = new ArrayList<>(50);
}
mDataChunks.add(inBytes);
if (mLength != null)
{
mLength += inBytes.length;
}
else
{
mLength = (long) inBytes.length;
}
return this;
}
//--------------------------------------------------------------------------
public FileBytes appendData(FileBytes inFileBytes)
throws IOException
{
if (inFileBytes.length() > 0)
{
if (null == mDataChunks)
{
mDataChunks = new ArrayList<>(50);
}
for (byte[] bytes : inFileBytes.mDataChunks)
{
mDataChunks.add(bytes);
}
if (mLength != null)
{
mLength += inFileBytes.length();
}
else
{
mLength = (long) inFileBytes.length();
}
}
return this;
}
//--------------------------------------------------------------------------
public byte[] getBytes()
{
ByteArrayOutputStream stream;
try
{
stream = new ByteArrayOutputStream();
StreamUtil.writeToStream(getDataStream(), stream);
}
catch (IOException e)
{
throw new ProgrammingException(e);
}
return stream.toByteArray();
}
//--------------------------------------------------------------------------
public InputStream getDataStream()
{
InputStream dataStream = null;
if (CollectionUtil.hasValues(mDataChunks))
{
dataStream = new DataStreamer();
}
return dataStream;
}
//--------------------------------------------------------------------------
public void writeData(OutputStream inStream)
throws IOException
{
if (CollectionUtil.hasValues(mDataChunks))
{
for (byte[] chunk : mDataChunks)
{
inStream.write(chunk);
}
}
}
//--------------------------------------------------------------------------
public static void streamAsZipFile(OutputStream inWriteTarget, String inBaseZipFileName, List inWorklists)
throws IOException
{
ZipOutputStream zipStream = null;
try
{
zipStream = new ZipOutputStream(inWriteTarget);
for (FileBytes worklist : inWorklists)
{
ZipEntry zipEntry = new ZipEntry(inBaseZipFileName + "/" + worklist.name());
zipStream.putNextEntry(zipEntry);
worklist.writeData(zipStream);
zipStream.closeEntry();
}
}
finally
{
if (zipStream != null)
{
zipStream.finish();
}
}
}
//###########################################################################
// INNER CLASS
//###########################################################################
private class DataStreamer extends InputStream
{
private byte[] mCurrentChunk;
private int mCurrentChunkIndex;
private int mByteIndex;
private boolean mDone = false;
int count = 0;
//-----------------------------------------------------------------------
public DataStreamer()
{
mCurrentChunkIndex = 0;
}
//-----------------------------------------------------------------------
public int read()
{
return (mDone ? -1 : getNextByte());
}
//-----------------------------------------------------------------------
@Override
public int read(byte b[], int off, int len)
throws IOException
{
if (b == null)
{
throw new NullPointerException();
}
else if (off < 0 || len < 0 || len > b.length - off)
{
throw new IndexOutOfBoundsException();
}
else if (len == 0)
{
return 0;
}
int c = read();
if (c == -1 && mDone)
{
return -1;
}
b[off] = (byte) c;
int i = 1;
for (; i < len; i++)
{
c = read();
if (c == -1 && mDone)
{
break;
}
b[off + i] = (byte) c;
}
return i;
}
//-----------------------------------------------------------------------
private byte getNextByte()
{
if (null == mCurrentChunk)
{
mCurrentChunk = mDataChunks.get(mCurrentChunkIndex);
mByteIndex = 0;
}
byte nextByte = mCurrentChunk[mByteIndex++];
if (mByteIndex >= mCurrentChunk.length)
{
// This is the last byte in this chunk.
mCurrentChunk = null;
mCurrentChunkIndex++;
if (mCurrentChunkIndex < 0 || mCurrentChunkIndex == mDataChunks.size())
{
// This was the last chunk.
mDone = true;
}
}
return nextByte;
}
}
}