kamranzafar / jtar

JTar is a simple Java Tar library, that provides an easy way to create and read tar files using IO streams. The API is very simple to use and similar to the java.util.zip package.
https://kamranzafar.org
Apache License 2.0
145 stars 45 forks source link

Wrap arbitary InputStream as tar InputStream #23

Open plamentotev opened 7 years ago

plamentotev commented 7 years ago

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.