I am trying to unzip a response from a .net middleware. The response has been ziped using GZipStream.
GZipStream zipStream = new GZipStream(fileStream, CompressionMode.Compress, true);
when I used GZIPInputStream in java to unzip the file. I am getting an IOException with message "not in zip format" in the following code.
GZIPInputStream gzin = new GZIPInputStream(response);
I tried this too.
ByteArrayInputStream memstream = new ByteArrayInputStream(buffer2);
GZIPInputStream gzin = new GZIPInputStream(memstream);
Any help or suggestions are welcomed.
Thanks in advance
Try something like this
GZIPInputStream gis = null;
FileOutputStream fos = null;
try {
gis = new GZIPInputStream(new FileInputStream("pathOfTheGZipFile"));
fos = new FileOutputStream("pathOfDecompressedFile");
byte[] buffer = new byte[gis.available()];
int len;
while((len = gis.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
fos.close();
gis.close();
}
I have finally figured out the solution, In the response returned by the server first few bytes were not zipped so if any one is facing the same issue you just need to check the bytes. After I removed those bytes from response. It started working.
Related
I have a BLOB file which I have got from the DB team. I know that its a PDF document (I opened using Notepad++ and I could see the file name) and I need to convert the same using java. I have checked for few examples and I couldn't find any example where the BLOB file itself is taken as an input instead of taking directly from the DB (Resultset). Can anyone please give some pointers as to how I can accomplish this?
Thanks in advance!
I have tried below,
File file = new File("C:/Users/User1/Desktop/0LK54E33K1477e2MCEU25JV0G8MG418S007N45JU.BLOB0");
FileInputStream fis = new FileInputStream(file);
//System.out.println(file.exists() + "!!");
//InputStream in = resource.openStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum); //no doubt here is 0
//Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
System.out.println("read " + readNum + " bytes,");
}
} catch (IOException ex) {
//Logger.getLogger(genJpeg.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] bytes = bos.toByteArray();
//below is the different part
File someFile = new File("C:/Users/User1/Desktop/Test.pdf");
FileOutputStream fos = new FileOutputStream(someFile);
fos.write(bytes);
fos.flush();
fos.close();
Im trying to stream a zip file as output for the user to download. I create a zipOutputStream, and have tried to send it into the vertx http response.
However this download a corrupt zip file or hangs
public void download(RoutingContext routingContext) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos)) {
for (int i = 0; i < 2; i++) {
String fileName = "test" + i + ".csv";
File tempFile = createTempFile("test" + i);
tempFile.deleteOnExit();
InputStream is = new FileInputStream(tempFile);
byte[] buffer = new byte[is.available()];
is.read(buffer);
ZipEntry entry = new ZipEntry(fileName);
zos.putNextEntry(entry);
try {
zos.write(buffer, 0, buffer.length);
zos.closeEntry();
String b64String = Base64.encodeBase64String(baos.toByteArray());
routingContext.response()
.setChunked(true)
.putHeader(HttpHeaders.CONTENT_TYPE, "application/zip")
.putHeader("Content-Disposition", "attachment; filename=\"test.zip\"")
.putHeader(HttpHeaders.TRANSFER_ENCODING, "chunked")
.putHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(b64String.length()));
routingContext.response().write(b64String);
routingContext.response().end();
routingContext.response().close();
} finally {
baos.close();
}
}
}
catch(Exception ex) {
}
}
I worked out the solution. I wrapped the vertx httpResponse in an outputStream, and pushed that into zipOutputStream. And it worked, by setting chunked to true.
For very big files, you can use streaming to avoid loading them completely into RAM:
AsyncInputStream fileContent = new AsyncInputStream(routingContext.vertx(), fileInputStream);
fileContent.endHandler((ev) -> {
routingContext.response().end();
});
Pump.pump(fileContent, routingContext.response()).start();
Unfortunately, AsyncInputStream (wrapper for InputStream into ReadStream) is not yet part of VertX framework so you have to implement it yourself or find some open source implementation.
I would like to use bufferedInputStream and bufferedOutputStream to copy large binary files from source file to destination file.
Here is my code:
byte[] buffer = new byte[1000];
try {
FileInputStream fis = new FileInputStream(args[0]);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(args[1]);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int numBytes;
while ((numBytes = bis.read(buffer))!= -1)
{
bos.write(buffer);
}
//bos.flush();
//bos.write("\u001a");
System.out.println(args[0]+ " is successfully copied to "+args[1]);
bis.close();
bos.close();
} catch (IOException e)
{
e.printStackTrace();
}
I can successfully copy but then I use
cmp src dest
in the command line to compare two files.
The error message
cmp: EOF on files
appears. May I know where I was wrong?
This is the mistake:
bos.write(buffer);
You're writing out the whole buffer, even if you only read data into part of it. You should use:
bos.write(buffer, 0, numBytes);
I'd also suggest using try-with-resources if you're using Java 7 or later, or put the close calls in a finally block otherwise.
As Steffen notes, Files.copy is a simpler approach if that's available to you.
If you are using Java 8 try the Files.copy(Path source, Path target) method.
you need to close your FileOutputStream and FileInputStream
Also you can use FileChannel to copy like as follows
FileChannel from = new FileInputStream(sourceFile).getChannel();
FileChanngel to = new FileOutputStream(destFile).getChannel();
to.transferFrom(from, 0, from.size());
from.close();
to.close();
You could use IOUtils from apatch-commons library
I think copyLarge fucntion it that you need
I need a very simple function that allows me to read the first 1k bytes of a file through FTP. I want to use it in MATLAB to read the first lines and, according to some parameters, to download only files I really need eventually. I found some examples online that unfortunately do not work. Here I'm proposing the sample code where I'm trying to download one single file (I'm using the Apache libraries).
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("data.site.org");
// filename to be downloaded.
String filename = "filename.Z";
fos = new FileOutputStream(filename);
// Download file from FTP server
InputStream stream = client.retrieveFileStream("/pub/obs/2008/021/ab120210.08d.Z");
byte[] b = new byte[1024];
stream.read(b);
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
the error is in stream which is returned empty. I know I'm passing the folder name in a wrong way, but I cannot understand how I have to do. I've tried in many way.
I've also tried with the URL's Java classes as:
URL url;
url = new URL("ftp://data.site.org/pub/obs/2008/021/ab120210.08d.Z");
URLConnection con = url.openConnection();
BufferedInputStream in =
new BufferedInputStream(con.getInputStream());
FileOutputStream out =
new FileOutputStream("C:\\filename.Z");
int i;
byte[] bytesIn = new byte[1024];
if ((i = in.read(bytesIn)) >= 0) {
out.write(bytesIn);
}
out.close();
in.close();
but it is giving an error when I'm closing the InputStream in!
I'm definitely stuck. Some comments about would be very useful!
Try this test
InputStream is = new URL("ftp://test:test#ftp.secureftp-test.com/bookstore.xml").openStream();
byte[] a = new byte[1000];
int n = is.read(a);
is.close();
System.out.println(new String(a, 0, n));
it definitely works
From my experience when you read bytes from a stream acquired from ftpClient.retrieveFileStream, for the first run it is not guarantied that you get your byte buffer filled up. However, either you should read the return value of stream.read(b); surrounded with a cycle based on it or use an advanced library to fill up the 1024 length byte[] buffer:
InputStream stream = null;
try {
// Download file from FTP server
stream = client.retrieveFileStream("/pub/obs/2008/021/ab120210.08d.Z");
byte[] b = new byte[1024];
IOUtils.read(stream, b); // will call periodically stream.read() until it fills up your buffer or reaches end-of-file
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
}
I cannot understand why it doesn't work. I found this link where they used the Apache library to read 4096 bytes each time. I read the first 1024 bytes and it works eventually, the only thing is that if completePendingCommand() is used, the program is held for ever. Thus I've removed it and everything works fine.
I call a service which returns a gzipped file. I have the data as an InputStream (courtesy of javax.activation.DataHandler.getInputStream();) from the response.
What I would like to do is, without writing anything to disk, get an InputStream of the decompressed data in the file that is in the archive. The compressed file in this case is an xml document that I am trying to unmarshal using javax.xml.bind.Unmarshaller which takes an InputStream.
I'm currently trying to write the InputStream to an OutputStream (decompressing the data) and then I'll need to write it back to an InputStream. It's not working yet so I thought I would see if there was a better (I would hope so) approach.
I can write the initial InputStream to disk and get a gz file, and then read that file, get the compressed file out of it and go from there but I'd rather keep it all in memory is possible.
Update 1: Here is my current (not working - get a "Not in GZIP format" exception):
ByteArrayInputStream xmlInput = null;
try {
InputStream in = dh.getInputStream(); //dh is a javax.activation.DataHandler
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int bytes_read = 0;
byte[] dataBuf = new byte[4096];
while ((bytes_read = bis.read(dataBuf)) != -1) {
bo.write(dataBuf, 0, bytes_read);
}
ByteArrayInputStream bin = new ByteArrayInputStream(bo.toByteArray());
GZIPInputStream gzipInput = new GZIPInputStream(bin);
ByteArrayOutputStream out = new ByteArrayOutputStream();
dataBuf = new byte[4096];;
bytes_read = 0;
while ((bytes_read = gzipInput.read(dataBuf)) > 0) {
out.write(dataBuf, 0, bytes_read);
}
xmlInput = new ByteArrayInputStream(out.toByteArray());
If instead of writing to a ByteArrayOutputStream I write to a FileOutputStream the first time around I get a compressed file (which I can manually open to get the xml file within) and the service (eBay) says it should be a gzip file so I'm not sure why I get a "Not in GZIP format" error.
Update 2: I tried something a little different - same error ("Not in GZIP format"). Wow, I just tried to end that parenthesis with a semi-colon. Anyways, here is my second attempt, which still does not work:
ByteArrayInputStream xmlInput = null;
try {
GZIPInputStream gzipInput = new GZIPInputStream(dh.getInputStream());
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int bytes_read = 0;
byte[] dataBuf = new byte[4096];
while ((bytes_read = gzipInput.read(dataBuf)) != -1) {
bo.write(dataBuf, 0, bytes_read);
}
xmlInput = new ByteArrayInputStream(bo.toByteArray());
Decorate the input stream with a GZIPInputStream.
InputStream decompressed = new GZIPInputStream(compressed);
The following code should work. Keep in mind you'll have to handle exceptions properly.
OutputStream out = null;
InputStream in = null;
try {
out = /* some output stream */;
in = new java.util.GZIPInputStream(/*some stream*/);
byte[] buffer = new byte[4096];
int c = 0;
while (( c = in.read(buffer, 0, 4096)) > 0) {
out.write(buffer, 0, c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
Take a look at GZIPInputStream. Here's an example; the class handles this very transparently, it's almost no work to use.