How to compress and decompress between C++ and Java? - java

all
I faced a problem to compress and decompress between java and C++.
Here is Java code runs at server.
public static byte[] CompressByDeflater(byte[] toCompress) throws IOException
{
ByteArrayOutputStream compressedStream = new ByteArrayOutputStream();
DeflaterOutputStream inflater = new DeflaterOutputStream(compressedStream);
inflater.write(toCompress, 0, toCompress.length);
inflater.close();
return compressedStream.toByteArray();
}
public static byte[] DecompressByInflater(byte[] toDecompress) throws IOException
{
ByteArrayOutputStream uncompressedStream = new ByteArrayOutputStream();
ByteArrayInputStream compressedStream = new ByteArrayInputStream(toDecompress);
InflaterInputStream inflater = new InflaterInputStream(compressedStream);
int c;
while ((c = inflater.read()) != -1)
{
uncompressedStream.write(c);
}
return uncompressedStream.toByteArray();
}
And I receive a binary file from server.
Then I have to decompress it using C++.
Where do I start with?

Your compression program uses zlib (see JDK documentation), so you need to use a C++ zlib library to decompress its output.
The zlib documentation is the place to start.

Related

How to convert TarArchiveOutputStream to byte array without saving into file system

I have a byte array representation of a tar.gz file. I want to get the byte array representation of a new tar.gz file after adding a new config file. I wanted to do this entirely in the code itself without creating any files to the local disk.
Below is my code in java
InputStream fIn = new ByteArrayInputStream(inputBytes);
BufferedInputStream in = new BufferedInputStream(fIn);
GzipCompressorInputStream gzIn = new GzipCompressorInputStream(in);
TarArchiveInputStream tarInputStream = new TarArchiveInputStream(gzIn);
ByteArrayOutputStream fOut = new ByteArrayOutputStream();
BufferedOutputStream buffOut = new BufferedOutputStream(fOut);
GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(buffOut);
TarArchiveOutputStream tarOutputStream = new TarArchiveOutputStream(gzOut);
ArchiveEntry nextEntry;
while ((nextEntry = tarInputStream.getNextEntry()) != null) {
tarOutputStream.putArchiveEntry(nextEntry);
IOUtils.copy(tarInputStream, tarOutputStream);
tarOutputStream.closeArchiveEntry();
}
tarInputStream.close();
createTarArchiveEntry("config.json", configData, tarOutputStream);
tarOutputStream.finish();
// Convert tarOutputStream to byte array and return
private static void createTarArchiveEntry(String fileName, byte[] configData, TarArchiveOutputStream tOut)
throws IOException {
ByteArrayInputStream baOut1 = new ByteArrayInputStream(configData);
TarArchiveEntry tarEntry = new TarArchiveEntry(fileName);
tarEntry.setSize(configData.length);
tOut.putArchiveEntry(tarEntry);
byte[] buffer = new byte[1024];
int len;
while ((len = baOut1.read(buffer)) > 0) {
tOut.write(buffer, 0, len);
}
tOut.closeArchiveEntry();
}
How to convert tarOuputStream to byte array?
You have opened the several OutputStream instances, but you haven't closed them yet. Or more precisely, you haven't "flushed" the content, specially the BufferedOutputStream instance.
BufferedOutputStream is using an internal buffer to "wait" for the data written to the target OutputStream. It does so until there is a reason to do so. One of these "reasons" is to call the BufferedOutputStream.flush() method:
public void flush() throws IOException
Flushes this buffered output stream. This forces any buffered output bytes to be written out to the
underlying output stream.
One other "reason" is to close the stream so it will write the remaining bytes before closing the stream.
In your case the bytes being written are still stored in the internal buffer. Depending on your code structure, you can simply close all the OutputStream instances you have, so the bytes finally gets written to the ByteArrayOutputStream:
tarInputStream.close();
createTarArchiveEntry("config.json", configData, tarOutputStream);
tarOutputStream.finish();
// Convert tarOutputStream to byte array and return
tarOutputStream.close();
gzOut.close();
buffOut.close();
fOut.close();
byte[] content = fOut.toByteArray();

How to convert Attachment Object to ByteArray in JAVA

I am writing a web service in JAVA using Apache CXF.
So, I have a method whose prototype is following:
public Response upload(#Multipart("id") int Id,
#Multipart("file") Attachment attachment) {
Now, I want to convert this attachment to byte[] . How can I do it?
Here is how you can read the content of the attachment and store it inside a byte array. Alternatively you can write directly to an OutputStream and skip the conversion to byte[].
DataHandler dataHandler = attachment.getDataHandler();
final byte[] data;
try (InputStream inputStream = dataHandler.getInputStream()) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final byte[] buffer = new byte[4096];
for (int read = inputStream.read(buffer); read > 0; read = inputStream.read(buffer)) {
outputStream.write(buffer, 0, read);
}
data = outputStream.toByteArray();
}
//todo write data to BLOB
If you want to be more memory efficient or if the attachment does not fit into memory, you can write directly to the blob's output stream. Just replace the ByteArrayOutputStream with OutputStream outputStream = blob.setBinaryStream(1);

Reading a bin file in Java

I know that there are some similar questions in the site, but they could not provide me a helpful answer. What is the best/most efficient way to read a .bin file in Java line by line? Which classes and methods should someone use to open it and get the data? Could Bufferedreader do the job or is it only for text files;
Binary file don't have lines, but you must know the format of the file to know what structure exists (headers, structs,etc) and write a parser.
You can use BufferedInputStream, see the following:
http://www.javapractices.com/topic/TopicAction.do?Id=245
Read structured data from binary file -?
This should do it.
public byte[] readFromStream(InputStream inputStream) throws Exception
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
byte[] data = new byte[4096];
int count = inputStream.read(data);
while(count != -1)
{
dos.write(data, 0, count);
count = inputStream.read(data);
}
return baos.toByteArray();
}

How to zip a single string with ZipOutputStream and save as a readable string

I tried to compress a string with DeflaterOutputStream and converted the output with base64 to save the result in another string
public static String compress(String str) throws IOException {
byte[] data = str.getBytes("UTF-8");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
java.util.zip.Deflater compresser = new java.util.zip.Deflater(java.util.zip.Deflater.BEST_COMPRESSION, true);
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(stream, cozmpresser);
deflaterOutputStream.write(data);
deflaterOutputStream.close();
byte[] output = stream.toByteArray();
return Base64Coder.encodeLines(output);
}
Now i wish to try ZipOutputStream. i tried
public static String compress(String str) throws IOException {
byte[] data = str.getBytes("UTF-8");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ZipOutputStream deflaterOutputStream = new ZipOutputStream(stream);
deflaterOutputStream.setMethod(ZipOutputStream.DEFLATED);
deflaterOutputStream.setLevel(8);
deflaterOutputStream.write(data);
deflaterOutputStream.close();
byte[] output = stream.toByteArray();
return Base64Coder.encodeLines(output);
}
But dont work. ZipOutputStream seems orientated to a structure of folders and files
how can I do?
ZipOutputStream is intended to produce a Zip file, which, as you noticed, is generally used as a container for files and folders (a "compressed folder" or "compressed directory tree", in other words).
If you merely want to compress a string and then convert it to some printable form, ZipOutputStream isn't really the right choice. GZIPOutputStream is more appropriate to that purpose, in my opinion.
Since you marked this question with an android tag, note the comment here: http://developer.android.com/reference/java/util/zip/GZIPOutputStream.html
Using GZIPOutputStream is a little easier than ZipOutputStream because GZIP is only for compression, and is not a container for multiple files.

how can i read from a binary file?

I want to read a binary file that its size is 5.5 megabyte(a mp3 file). I tried it with fileinputstream but it took many attempts. If possible, I want to read file with a minimal waste of time.
You should try to use a BufferedInputStream around your FileInputStream. It will improve the performance significantly.
new BufferedInputStream(fileInputStream, 8192 /* default buffer size */);
Furthermore, I'd recommend to use the read-method that takes a byte array and fills it instead of the plain read.
There are useful utilities in FileUtils for reading a file at once. This is simpler and efficient for modest files up to 100 MB.
byte[] bytes = FileUtils.readFileToByteArray(file); // handles IOException/close() etc.
Try this:
public static void main(String[] args) throws IOException
{
InputStream i = new FileInputStream("a.mp3");
byte[] contents = new byte[i.available()];
i.read(contents);
i.close();
}
A more reliable version based on helpful comment from #Paul Cager & Liv related to available's and read's unreliability.
public static void main(String[] args) throws IOException
{
File f = new File("c:\\msdia80.dll");
InputStream i = new FileInputStream(f);
byte[] contents = new byte[(int) f.length()];
int read;
int pos = 0;
while ((read = i.read(contents, pos, contents.length - pos)) >= 1)
{
pos += read;
}
i.close();
}

Categories