How to get a binary file from a remote php script response? - java

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();
}
}

Related

How to convert loaded bytes into image without ImageIO.read()

I can't use ImageIO.read() because of my own restrictions. I can only load bytes after GET request and I need to save this bytes to file as image. But it seems to me, that there also loads some extra data, which browser usually filter (maybe response headers). So I get the array of raw bytes which I even can't open as image.
What should I do with this bytes?
Example:
byte[] buf = ContentLoader.loadBytes(new URL("http://images.visitcanberra.com.au/images/canberra_hero_image.jpg"));
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\image.jpg"));
fileOutputStream.write(buf);
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
loadBytes() method:
public static byte[] loadBytes(URL url) {
ByteArrayOutputStream boutArray = new ByteArrayOutputStream();
try {
URLConnection connection = url.openConnection();
BufferedInputStream bin = new BufferedInputStream(connection.getInputStream());
byte[] buffer = new byte[1024 * 16];
while (bin.read(buffer) != -1) {
boutArray.write(buffer);
boutArray.flush();
}
bin.close();
} catch (Exception e) {
return null;
}
return boutArray.toByteArray();
}
Usual problems. The standard way to copy a stream in Java is:
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
out.close();
in.close();
Note that you need to store the result returned by read() into a variable; that you need to use it in the next write() call; that you shouldn't flush() inside a loop; and that you need to close the input and output streams.
And why you're using a ByteArrayInputStream at all is a mystery. It's just a waste of time and space. Read directly from the URL input stream, and write directly to the FileOutputStream.
The following code works for me:-
URL url = new URL("my url...");
InputStream is = url.openStream();
OutputStream os = new FileOutputStream("img.jpg");
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();

Need to improve performance in file unzipping from DB

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.

Insufficient System resources exist to complete the requested services

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();
}

Not able to process big file inside a zip file using ZipInputStream

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();
}

How do I get the InputStream of decompressed data from an InputStream of GZIPed data?

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.

Categories

Resources