android : Zip Folder is invalid - java

i have a created 3 xml files and compressed into a zip folder . The folder is send from server. When i download the zip folder through browser, its working properly and can extract the files. But when i download it from android application and store in SD card, it is corrupted. I pulled the file from SD card to computer and tried to extract the folder, it shows Zip Folder is invalid . My code is given below :
DefaultHttpClient httpclient1 = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(
Configuration.URL_FEED_UPDATE);
byte[] responseByte = httpclient1.execute(httpPostRequest,
new BasicResponseHandler()).getBytes();
InputStream is = new ByteArrayInputStream(responseByte);
// ---------------------------------------------------
File file1 = new File(Environment
.getExternalStorageDirectory() + "/ast");
file1.mkdirs();
//
File outputFile = new File(file1, "ast.zip");
FileOutputStream fos = new FileOutputStream(outputFile);
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
When I used
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(is));
The ZipInputStream can't store values from stream.

I'd guess that your main mistake is where you get the input stream. What you are actually doing is to get the server response as String (BasicResponseHandler) and then converting that to bytes again. Since Java is all UTF-8 this most likely does not work.
Better try something like
HttpResponse response = httpclient1.execute(httpPostRequest);
InputStream is = response.getEntity().getContent()
(And do better null pointer checking, read the content in a try-catch block and make sure you close all resources in a finally block.)

Related

Android: Corrupted characters in PDF

I'm using HttpURLConnection to get a PDF file from the server then saving that PDF to the user's phone. Getting the file is working perfectly, but when saving, some files contain corrupted characters.
InputStream in = null;
OutputStream fileOutput = null;
try {
File file = new File(path);
file.mkdirs();
file = new File(path + File.separator + fileName + "." + fileExentsion);
file.createNewFile();
fileOutput = new FileOutputStream(file);
final byte[] buffer = new byte[1024];
int read;
in = conn.getInputStream();
while ((read = in.read(buffer)) != -1) {
fileOutput.write(buffer, 0, read);
}
fileOutput.flush();
return Uri.fromFile(file).toString(); // To open an intent in onPostExecute()
}
I tried using BufferedReader and BufferedWriter but the OS couldn't open the file after being saved. It is really weird because the same strings appears in other files correctly. And when downloading the file from a desktop, it looks good too.

Java copying a file out of a jar

I am trying to copy a file (Base.jar) to the same directory as the running jar file
I keep getting a corrupted jar file, that still holds the correct class structure when opened with winrar. What am I doing wrong? (I have also tried without the ZipInputStream, but that was no help) the byte[] is 20480 because that is size of it on the disk.
my code:
private static void getBaseFile() throws IOException
{
InputStream input = Resource.class.getResourceAsStream("Base.jar");
ZipInputStream zis = new ZipInputStream(input);
byte[] b = new byte[20480];
try {
zis.read(b);
} catch (IOException e) {
}
File dest = new File("Base.jar");
FileOutputStream fos = new FileOutputStream(dest);
fos.write(b);
fos.close();
input.close();
}
InputStream input = Resource.class.getResourceAsStream("Base.jar");
File fileOut = new File("your lib path");
OutputStream out = FileUtils.openOutputStream(fileOut);
IOUtils.copy(in, out);
in.close();
out.close();
and handle exceptions
No need to use ZipInputStream, unless you want to unzip the contents into memory and read.
Just use BufferedInputStream(InputStream) or BufferedReader(InputStreamReader(InputStream)).
did some more googling found this: (Convert InputStream to byte array in Java) worked for me
InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
(it looks very simular to the src for IOUtils.copy())
ZipInputStream is for reading files in the ZIP file format by entry. You need to copy the whole file (resource) that is you need to simply copy all bytes from InputStream no matter what format is. The best way to do it in Java 7 is this:
Files.copy(inputStream, targetPath, optionalCopyOptions);
see API for details

Java : download file outside server context

I need to save a file and download file in directory outside server context.
I am using Apache Tomacat
I am able to do this in directory present in webapps directory of application
If my directory structure is as follows,
--src
--WebContent
-- uploaddir
-- myfile.txt
Then I am able to download in by simply.
download
But, problem is when file is in some other directory say d:\\uploadedfile\\myfile.txt
then I wont be able to download it, as resource is not in server context as above.
I have file path to uuid mapping,
like,
d:\\uploadedfiles\\myfile.txt <-> some_uuid
then I want file should be downloaded, on click of following,
download
So, How to make file downloadable when it is outside the server context,
I heard about getResourceAsStream() method which would do this , But would any one help me on how to do this, probably with simple code snippet?
Try the below code which you can write in filedownloadservet. Fetch the file name from the request parameter and then read and write the file.
If you need to do some security checks then do that before processing the request.
File file = new File("/home/files", "file name which user wants to download");
response.setContentType(getServletContext().getMimeType(file.getName()));
response.setContentLength(file.length());
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
outputStream = new BufferedOutputStream(response.getOutputStream());
byte[] buf = new byte[2048];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
//log it
}
}
// do the same for input stream also
}
here i found the answer,
response.setContentType("application/msword");
response.setHeader("Content-Disposition","attachment;filename=downloadname.doc");
File file=new File("d:\\test.doc");
InputStream is=new FileInputStream(file);
int read=0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
while((read = is.read(bytes))!= -1){
os.write(bytes, 0, read);
}
os.flush();
os.close();
Base path will not work that is for HTML and it works if the base path is also exposed by your web server which does not look like case here.
To download an arbitary file you need to open the file using a FileInputStream (and surround it by a buffered input stream), read a byte, then send that byte from your servlet to the client.
Then there are security concerns, so should google that (basically not give access to any file but only file that is to be shared, audit download etc as needed.
Again in your servlet set the mime type etc and then open a input stream and write the bytes to the output stream to client

Zipping Files using util.zip No directory

I have the following situation:
I am able to zip my files with the following method:
public boolean generateZip(){
byte[] application = new byte[100000];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// These are the files to include in the ZIP file
String[] filenames = new String[]{"/subdirectory/index.html", "/subdirectory/webindex.html"};
// Create a buffer for reading the files
try {
// Create the ZIP file
ZipOutputStream out = new ZipOutputStream(baos);
// Compress the files
for (int i=0; i<filenames.length; i++) {
byte[] filedata = VirtualFile.fromRelativePath(filenames[i]).content();
ByteArrayInputStream in = new ByteArrayInputStream(filedata);
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(filenames[i]));
// Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(application)) > 0) {
out.write(application, 0, len);
}
// Complete the entry
out.closeEntry();
in.close();
}
// Complete the ZIP file
out.close();
} catch (IOException e) {
System.out.println("There was an error generating ZIP.");
e.printStackTrace();
}
downloadzip(baos.toByteArray());
}
This works perfectly and I can download the xy.zip which contains the following directory and file structure:
subdirectory/
----index.html
----webindex.html
My aim is to completely leave out the subdirectory and the zip should only contain the two files. Is there any way to achieve this?
(I am using Java on Google App Engine).
Thanks in advance
If you are sure the files contained in the filenames array are unique if you leave out the directory, change your line for constructing ZipEntrys:
String zipEntryName = new File(filenames[i]).getName();
out.putNextEntry(new ZipEntry(zipEntryName));
This uses java.io.File#getName()
You can use Apache Commons io to list all your files, then read them to an InputStream
Replace the line below
String[] filenames = new String[]{"/subdirectory/index.html", "/subdirectory/webindex.html"}
with the following
Collection<File> files = FileUtils.listFiles(new File("/subdirectory"), new String[]{"html"}, true);
for (File file : files)
{
FileInputStream fileStream = new FileInputStream(file);
byte[] filedata = IOUtils.toByteArray(fileStream);
//From here you can proceed with your zipping.
}
Let me know if you have issues.
You could use the isDirectory() method on VirtualFile

Create pdf through java.io

I tried creating a pdf file out of another one(in my local drive) using java.io. The thing is a file with a .pdf extension got created but im unable to open the file, it says the file is already in use and most importantly the size of the file is too large and it keeps on increasing (origin file size : 5,777kB and the newly created one file size as of now is 38,567kB). Im not that much of skilled java programmer but still i would appreciate if anyone can give me an explanation ..
String path = "D:\\priya_Docs\\Android pdfs\\Professional_Android_Application_Development.pdf";
File file = new File(path);
System.out.println("Located a file " + file.isFile());
String filesArray = file.getPath();
File getFile = file.getAbsoluteFile();
FileInputStream fis = new FileInputStream(getFile);
FileOutputStream fos = new FileOutputStream(
"D:\\priya_Docs\\Androiddoc.pdf");
for (int b = fis.read(); b != -1;) {
fos.write(b);
}
Simple use,
FileUtils.copyFile()
you meet the two problems
first,you have to close the resource: fis and fos,or it will say the file already in use
second,you have to use the byte[] to receive the data because pdf file is organized in byte arrays
String path = "D:\\priya_Docs\\Android pdfs\\Professional_Android_Application_Development.pdf";
File file = new File(path);
System.out.println("Located a file " + file.isFile());
String filesArray = file.getPath();
File getFile = file.getAbsoluteFile();
FileInputStream fis = new FileInputStream(getFile);
FileOutputStream fos = new FileOutputStream(
"D:\\priya_Docs\\Androiddoc.pdf");
byte[] buff=new byte[1024];
int len;
while((len=fis.read(buff))>=0) {
fos.write(buff,0,len);
}
fis.close();
fos.close();

Categories