Error while downloading the zip file from server to device? - java

I am using this code to download zip file from server
private static InputStream OpenHttpConnection(String urlString)
throws IOException
{
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try{
System.out.println("OpenHttpConnection called");
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestProperty("content-type", "binary/data");
httpConn.connect();
response = httpConn.getResponseCode();
System.out.println("response is"+response);
System.out.println(HttpURLConnection.HTTP_OK);
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
System.out.println("Connection Ok");
return in;
}
}
catch (Exception ex)
{
throw new IOException("Error connecting");
}
return in;
}
and
private static void saveToInternalSorage(InputStream in,String filename,Context ctx){
//fos =openFileOutput(filename, Context.MODE_WORLD_READABLE);
try {
// System.out.println("mypath = "+mypath);
//fos = new FileOutputStream(mypath);
FileOutputStream fos = (ctx).openFileOutput(filename, Context.MODE_WORLD_READABLE);
byte[] buffer=new byte[1024];
int len1 ;
while ( (len1 = in.read(buffer) )!=-1 ) {
fos.write(buffer);
}
// Use the compress method on the BitMap object to write image to the OutputStream
} catch (Exception e) {
e.printStackTrace();
}
}
The zip file which is downloaded is corrupted , the actual size of the file is 3.5kb but the downloaded file is of 5kb .What is the problem with the code please help?

This
while ( (len1 = in.read(buffer) )!=-1 ) {
fos.write(buffer);
}
You are writing the entire buffer in each iteration (1024 bytes). You should only write len1 bytes (number of bytes read).
On a side-note, you may want to look at using some higher level abstraction libraries for stuff like HTTP and stream manipulation. Apache Commons HttpComponents and Commons IO for instance.

httpConn.setDoOutput(false);
httpConn.setRequestProperty("Content-Type", "application/octet-stream");
httpConn.setRequestProperty("Content-Length", String.valueOf(file.length());
while (... > 0) {
fos.write(buffer, 0, len1);
fos.close();

Write only the bytes which are filled in the buffer i.e only len1 bytes. It will solve your problem as if the buffer is not filled completely, we will write only those bytes which are read.
while ( (len1 = in.read(buffer) )!=-1 ) {
fos.write(subArray(buffer,len1));
}
//Method to create su-array
public byte[] subArray(byte[] arr, int length) {
byte temp[] = new byte[length];
for (int i = 0; i < length; i++) {
temp[i] = arr[i];
}
return temp;
}

Related

File download incomplete when application killed or destroy

When I am downloading a file from the server if suppose I killed or destroy the application means it will download only half of data how to resume download when application open or how to delete incomplete data in the file.
Any ideas?
private void downloadBookDetails(String pMainFolder, String pFileName, String pDownloadURL) {
Log.i(TAG, "Coming to this downloadBookDetails ");
try {
URL url = new URL(pDownloadURL);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File directory = new File(pMainFolder, pFileName);
FileOutputStream outStream = new FileOutputStream(directory);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
} catch (Exception e) {
//Add Network Error.
Log.e(TAG, "Download Error Exception " + e.getMessage());
e.printStackTrace();
}
}
You should use DownLoad Manager for downloads in your app. This will automatically handles all the things for you. Which is a system service that can handle long-running HTTP downloads.
UPDATE
If you want to download the file by your own then you can use it like below:
#SuppressLint("Wakelock")
#Override
protected String doInBackground(String... sUrl) {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
wl.acquire();
try {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
File SDCardRoot = Environment.getExternalStorageDirectory();
File file = new File(SDCardRoot,"/"+fileName);
int downloaded=0;
if(file.exists()){
downloaded=(int) file.length();
connection.setRequestProperty("Range", "bytes=" + (int) file.length() + "-");
}
else{
file.createNewFile();
}
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength()+(int)file.length();
// download the file
input = connection.getInputStream();
if(downloaded>0){
output = new FileOutputStream(file,true);
}
else{
output = new FileOutputStream(file);
}
byte data[] = new byte[1024];
long total = downloaded;
int count;
mProgressDialog.setMax(fileLength/1024);
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled())
return null;
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int)total/1024);
output.write(data, 0, count);
}
output.flush();
if (output != null)
output.close();
if (input != null)
input.close();
if (connection != null)
connection.disconnect();
wl.release();
return null;
} catch (Exception e) {
return e.toString();
}
}
catch (Exception e) {
return e.toString();
}
}

Missing Bottom part of image using getResponse().getOutputStream().write

i got the image from post response
PostMethod post = new PostMethod(action);
HttpClient httpClient = createHttpClient();
........
httpClient.executeMethod(post);
try {
log.info("post successfully");
String contentType = post.getResponseHeader("Content-type").getValue();
int contentLength = (int) post.getResponseContentLength();
byte[] responseBody = FileUtils.convertInputStreamtoByteArray(post.getResponseBodyAsStream());
log.info("get response sucessfully : size "+ responseBody.length +" contentLength " + contentLength);
return new ReturnBean(null, responseBody,contentType,contentLength);
} catch (Exception e) {
log.error(e.getMessage());
log.error(e.getStackTrace());
e.printStackTrace();
throw new ResponseFailedException(e.getMessage());
}
this is how i convert inputstream to byte array.
public static byte[] convertInputStreamtoByteArray(InputStream is){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buf = new byte[1024];
int i = 0;
while ((i = is.read(buf)) >= 0) {
baos.write(buf, 0, i);
}
is.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return baos.toByteArray();
}
this is how i return the image as a response.
byte[] imageSource = (byte[])returnStream.getBean();
log.info("imageSource " + imageSource.length);
getResponse().setContentType((String) returnStream.getBean2());
getResponse().setContentLength((Integer) returnStream.getBean3());
getResponse().getOutputStream().write(imageSource);
getResponse().getOutputStream().flush();
i was able to print out the image but im having a problem because the bottom part of it is missing . i checked the size of byte that i got and it is equal to the size of actual image.
when i used IOUtils.copyLarge(); instead of my method convertInputStreamtoByteArray
ServletOutputStream outputStream = getResponse().getOutputStream();
InputStream inputStream = (InputStream) returnStream.getBean();
IOUtils.copyLarge(inputStream , outputStream);
it works . i dont know what happen because i used it a while ago and it didnt work.

What should i use InputStream or FileInputStream or BufferedInputStream?

I am downloading few pdf and video file from the server and for that I am using InputStream to collect response but I want to know that which is better for my purpose InputStream or FileInputStream or BufferedInputStream ?
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(RootFile, fileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
I am using this for downloading videos
void downloadFile(String vidN){
int downloadedSize = 0;
int totalSize = 0;
try {
// here vidN is the name of the file like bird.mp4
// here sitepath is the path of the file
URL url = new URL(sitepath+vidN);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//connect
urlConnection.connect();
//set the path where we want to save the file
String RootDir = Environment.getExternalStorageDirectory()
+ File.separator + "VideoNR2";
File RootFile = new File(RootDir);
RootFile.mkdir();
//create a new file, to save the downloaded file
File file = new File(RootDir,""+vidN);
FileOutputStream fileOutput = new FileOutputStream(file);
//Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize = bufferLength;
}
//close the output stream when complete //
fileOutput.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
}
}

Upload Image to FTP Server using ADF Mobile Application

I want to upload an image to FTP Server. Currently i am using JDeveloper 12c(12.1.3.0).
My Code:
private static final int BUFFER_SIZE = 4096;
public String fileUploadMethod(String imagePath){
String ftpUrl = "ftp://";
String host = "http://192.168.0.42";
String user = "XXXXXX";
String pass = "XXXXXX";
String filePath = "783771-1.jpg";
String uploadPath = imagePath;
ftpUrl =ftpUrl + user +":"+ pass+"#"+host+"/"+filePath+";";
System.out.println("Upload URL: " + ftpUrl);
try {
URL url = new URL(ftpUrl);
URLConnection conn = url.openConnection();
OutputStream outputStream = conn.getOutputStream();
FileInputStream inputStream = new FileInputStream(uploadPath);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
System.out.println("File uploaded");
return "File uploaded";
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
I am getting an error MalFormedURLException i.e. in detail message "unknown protocol:ftp"
Is there any other option to upload an image using JDeveloper.
Any idea regarding this.
Thanks, Siddharth
Your ftpUrl is wrong. Remove http:// in the host variable. Should be ok then
I haven't really tried ftp upload. But I had tried with multipart form upload. As far as I know, MAF doesnt provide Out-Of-Box support for file upload. What I did was essential recreating the HTTP stream for the image upload.
The POC code is attached below. This may be definitely the CRUDEST implementation but I am not sure if there is a better way.
public void doUpload() {
try {
DeviceManager dm = DeviceManagerFactory.getDeviceManager();
String imgData =
dm.getPicture(50, DeviceManager.CAMERA_DESTINATIONTYPE_FILE_URI, DeviceManager.CAMERA_SOURCETYPE_CAMERA,
false, DeviceManager.CAMERA_ENCODINGTYPE_PNG, 0, 0);
imgData = imgData.substring(7, imgData.length());
int start = imgData.lastIndexOf('/');
String fileName = imgData.substring(start+1, imgData.length());
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
String requestMethod = RestServiceAdapter.REQUEST_TYPE_POST;
String requestEndPoint = restServiceAdapter.getConnectionEndPoint("serverBaseUrl");
String requestURI = "/workers/100000018080264";
String request = requestEndPoint + requestURI;
HashMap httpHeadersValue = new HashMap();
httpHeadersValue.put("X-ANTICSRF", "TRUE");
httpHeadersValue.put("Connection", "Keep-Alive");
httpHeadersValue.put("content-type","multipart/form-data; boundary=----------------------------4abf1aa47e18");
// Get the connection
HttpConnection connection = restServiceAdapter.getHttpConnection(requestMethod, request, httpHeadersValue);
OutputStream os = connection.openOutputStream();
byte byteBuffer[] = new byte[50];
int len;
//String temp is appended before the image body
String temp = "------------------------------4abf1aa47e18\r\nContent-Disposition: form-data; name=\"file\"; filename=\"" +fileName+ "\"\r\nContent-Type: image/jpeg\r\n\r\n";
InputStream stream = new ByteArrayInputStream(temp.getBytes("UTF-8"));
if (stream != null) {
while ((len = stream.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
stream.close();
}
FileInputStream in = new FileInputStream(imgData);
if (in != null) {
while ((len = in.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
in.close();
}
//The below String is appended after the image body
InputStream stream2 =new ByteArrayInputStream("\r\n------------------------------4abf1aa47e18--\r\n".getBytes("UTF-8"));
if (stream2 != null) {
while ((len = stream2.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
stream2.close();
}
int status = connection.getResponseCode();
InputStream inputStream = restServiceAdapter.getInputStream(connection);
ByteArrayOutputStream incomingBytes = new ByteArrayOutputStream() // get and process the response.
while ((len = inputStream.read(byteBuffer)) >= 0) {
incomingBytes.write(byteBuffer, 0, len);
}
String ret = incomingBytes.toString();
incomingBytes.close();
} catch (Exception e) {
e.printStackTrace();
}
}

How to send byte array from Android device to servlet

I need to send some byte array from android device to Servlet. For this I try to use next code:
Servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
DataInputStream in = new DataInputStream((InputStream)request.getInputStream());
response.setContentType("text/plain");
byte[] buffer = new byte[1024];
int len = 0;
File file;
file=new File(getServletContext().getRealPath("/POST_LOG!!!!.txt"));
if(!file.exists()){
file.createNewFile();
}
while ((len = in.read(buffer)) > 0) {
FileOutputStream fos = new FileOutputStream(getServletContext().getRealPath("/POST_LOG!!!!.txt"), true);
fos.write(buffer);
fos.close();
}
PrintWriter out = response.getWriter();
out.write("Done");
out.close();
Device side :
URL uploadUrl;
try {
uploadUrl = new URL(url);
HttpURLConnection c = (HttpURLConnection) uploadUrl
.openConnection();
c.setRequestMethod("POST");
c.setDoInput(true);
c.setDoOutput(true);
c.setUseCaches(false);
c.connect();
OutputStream out = c.getOutputStream();
for (int i = 0; i < 1000; i++) { // generate random bytes for
// uploading
byte[] buffer = new byte[256];
for (int j = 0; j < 256; j++) {
Random r = new Random();
buffer[j] = (byte) r.nextInt();
}
out.write(buffer);
out.flush();
}
out.close();
} catch (Exception e) {
MessageBox("Error. " + e.toString());
}
return (long) 0;
}
I dont understand why this code doesnt work. When I try to debug my POST method it even not called. I will grateful for your examples
I found the solution. I just changed my device-side code using custom InputStream.
Device side :
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new InputStreamEntity(new MyInputStream(),
4096 * 1024 * 10));
HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (ClientProtocolException e) {
e.printStackTrace();
httpPost.abort();
} catch (IOException e) {
e.printStackTrace();
httpPost.abort();
}
You have a lot of options:
send the byte values: 125,11,25,40 (that's a dumb option)
send it base64- or hex- encoded, and then decode it (use apache commons-codec)
submit it as multipart/form-data

Categories

Resources