jtar icon indicating copy to clipboard operation
jtar copied to clipboard

Wrap arbitary InputStream as tar InputStream

Open plamentotev opened this issue 7 years ago • 0 comments

Hi,

I work on an application that as a part of it's operation uploads a file to a Docker container. The Docker API accepts only tar files. That's why the client API expects InputStream containing tar file to be passed. Of course I could create temporary tar file but the file I want to upload could be of arbitrary size so I would rather avoid that. The tar file format does not compress the content of the file and essentially is headers plus the content of the file plus padding. So what I've done is to wrap the original InputStream and create a new one that will return tar file. Here is my code:

public static InputStream wrapInputStream(InputStream inputStream, String fileName,
                                          long size, long modificationTime, int fileMode)
{
    TarHeader header = TarHeader.createHeader(fileName, size, modificationTime, false, fileMode);
    TarEntry entry = new TarEntry(header);
    byte[] headerBytes = new byte[TarConstants.HEADER_BLOCK];
    entry.writeEntryHeader(headerBytes);
    InputStream headerInputStream = new ByteArrayInputStream(headerBytes);

    byte[] eofBytes = getPaddingAndEOF(size);
    InputStream eofInputStream = new ByteArrayInputStream(eofBytes);

    return new SequenceInputStream(Collections.enumeration(
                Arrays.asList(headerInputStream, inputStream, eofInputStream)
    ));
}

private static byte[] getPaddingAndEOF(long entrySize) {
    int paddingLen = TarConstants.DATA_BLOCK - ((int)(entrySize % TarConstants.DATA_BLOCK));

    return new byte[paddingLen + TarConstants.EOF_BLOCK];
}

Do you think such feature could be a valuable addition to the library? If you think so I could make the code more generic and open a pull request.

plamentotev avatar Mar 20 '17 19:03 plamentotev