I am getting zipped blob from db and using that blob in below way,
Ex:-
byte[] inputBlob = blobfile.getBytes(1, (int) blobfile.length());
After getting the blob, the way i got the zippedStream and passed it into another Class method(unzipper).
Ex:-
ByteArrayOutputStream zippedStream = null;
InputStream byteInputStream = null;
IParser parser = null;
byte[] buffer = null;
try {
zippedStream = new ByteArrayOutputStream();
byteInputStream = new ByteArrayInputStream(blob);
blob = null;
int bytes_read;
buffer = new byte[byteInputStream.available()];
while ((bytes_read = byteInputStream.read(buffer)) > 0) {
zippedStream.write(buffer, 0, bytes_read);
}
buffer = null;
byteInputStream.close();
byteInputStream = null;
}catch(Exception e){
e.printStackTrace();
}
unzipper method:
Ex:-
byte[] buffer = new byte[1024];
try {
InputStream decodedInput = new ByteArrayInputStream(zippedStream.toByteArray());
zippedStream.close();
zippedStream = null;
GZIPInputStream unzippedStream = new GZIPInputStream(decodedInput);
decodedInput.close();
decodedInput = null;
int bytes_read;
unzippedOutputstream = new ByteArrayOutputStream();
while ((bytes_read = unzippedStream.read(buffer)) > 0) {
unzippedOutputstream.write(buffer, 0, bytes_read);
}
buffer = null;
unzippedStream.close();
unzippedStream = null;
} catch (Exception ex) {
logger.setException(ex);
logger.error("unzipper", generateMsg("Exception occurred"));
}
Using this way my application got stucked some time, and performance was so bad.
Is there any optimize way to get the zippedstream file and unzipping that easily?
Is all this buffering really needed. Can you IParser parse a Stream?
InputStream zippedStream = ...
IParser parser = ...
parser.parse(new GZIPInputStream(zippedStream));
This will read compressed data, uncompressing as it goes which is much more efficient.
Related
How to resolve OutOfMemoryError in weblogic server
Increase Heap size - -Xmx10G, -Xms10G
implemented SFTP instead of FTP
byte[] fileArr = null;
ByteArrayOutputStream out;
StringBuilder strBuild = new StringBuilder();
strBuild.append(path);
strBuild.append(fileName);
InputStream inputStr = null;
BufferedInputStream bis = null;
ByteBuffer buffer = null;
ReadableByteChannel inputChannel = null;
WritableByteChannel outputChannel = null;
try {
inputStr = this.sftpClient.getInputStream(strBuild.toString());
if(READ_BUFFER_SIZE <= 0){
buffer = ByteBuffer.allocateDirect(DEFAULT_BUFFER_SIZE);
}
else{
buffer = ByteBuffer.allocateDirect(READ_BUFFER_SIZE);
}
bis = new BufferedInputStream(inputStr);
out = new ByteArrayOutputStream();
inputChannel = Channels.newChannel(bis);
outputChannel = Channels.newChannel(out);
while (inputChannel.read(buffer) > 0) {
buffer.flip();
outputChannel.write(buffer);
buffer.compact();
}
Need response in ByteArray of input file
In your coude I don't see where you close your Streams.
Probably server keeps your open buffers.
Insert a try-with-resource (https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) or close your streams in your code
Getting the above error when trying to download large data using HttpGet
String uri = "";
getMethod = executeGet(uri);
httpClient.executeMethod(getMethod);
InputStream istream = getMethod.getResponseBodyAsStream();
byte[] data = IOUtils.toByteArray(istream);
FileUtils.writeByteArraytoFile(new File("xxx.zip"),data)
You are using a temporary byte array that might be the cause of the problem.
You can directly write the content of the stream to your file.
String uri = "";
getMethod = executeGet(uri);
httpClient.executeMethod(getMethod);
InputStream istream = getMethod.getResponseBodyAsStream();
IOUtils.copy(istream, new FileOutputStream(new File("xxx.zip"));
You're reading the entire response into the byte[] (memory). Instead, you could stream the output as you read it from istream with something like,
File f = new File("xxx.zip");
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(f));) {
int c = -1;
while ((c = istream.read()) != -1) {
os.write(c);
}
} catch (Exception e) {
e.printStackTrace();
}
I am having a below mentioned java class which extracts a zip, and one by one convert its content to string and print to console.
Problem is, when the file present inside the zip is big ~80KB. Entire content is not getting displayed (only 3/4 of the data is getting converted to string and displayed in console).
Secondly below mentioned code is introducing null/space in between and also if the file size is small ~1KB
what is wrong in below mentioned code.
public static void main(String[] args) throws Exception {
byte[] buf = new byte[1024];
final int BUFFER = 1024;
String fName = "c:\\DOC00001.zip";
ZipInputStream zinstream = new ZipInputStream(
new FileInputStream(fName));
ZipEntry zentry = zinstream.getNextEntry();
while (zentry != null) {
byte data[] = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((zinstream.read(data, 0, BUFFER)) != -1) {
out.write(data);
}
InputStream is = new ByteArrayInputStream(out.toByteArray());
StringWriter writer = new StringWriter();
IOUtils.copy(is, writer, "UTF-8");
String response = writer.toString();
System.out.println(response);
zentry = zinstream.getNextEntry();
}
zinstream.close();
}
The read method is not guaranteed to read a full buffer; the number of bytes that have been read is returned. The correct way to extract data from a zip file, or any InputStream in general, would be:
byte[] data = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = zinstream.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, bytesRead);
}
Or, since you are already using IOUtils,
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(zinstream, out);
Or, given that you write to a ByteArrayOutputStream only to later write to a String, you can skip the ByteArrayOutputStream entirely:
while (zentry != null) {
StringWriter writer = new StringWriter();
IOUtils.copy(zinstream, writer, "UTF-8");
String response = writer.toString();
System.out.println(response);
zentry = zinstream.getNextEntry();
}
I'm calling a script that gives me a binary file (12345.cl), with binary data. The script is done, and it's working, if I paste it on the navigator I get the binary file.
Now I have a problem: How I transform the response of the script into a binary resource to use it in my app?
For the moment, i have this code:
public void decodeStream( String mURL ){
BufferedInputStream bis = new BufferedInputStream(new URL(mURL).openStream(), BUFFER_IO_SIZE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos, BUFFER_IO_SIZE);
copy(bis, bos);
bos.flush();
Then, I have a BufferedOutputStream with the response, but I don't know how to transform it into a binary resource to use it
I need to obtain a datainputstream with the file but I don't know how to achieve it
You can use following code:
public void decodeStream( String mURL, String ofile ) throws Exception {
InputStream in = null;
FileOutputStream out = null;
try {
URL url = new URL(mURL);
URLConnection urlConn = url.openConnection();
in = urlConn.getInputStream();
out = new FileOutputStream(ofile);
int c;
byte[] b = new byte[1024];
while ((c = in.read(b)) != -1)
out.write(b, 0, c);
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
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.