I am building the app which i want to unzip the database file from assets. But i am getting this errorjava.io.FileNotFoundException: /file:/android_asset/kjv.zip: open failed: ENOENT (No such file or directory).
I am using this code for unzip the file,
public void unzip(String _zipFile, String _targetLocation) {
//create target location folder if not exist
dirChecker(_targetLocation);
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
//create dir if required while unzipping
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_targetLocation + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch (Exception e) {
Log.e("error", e + "");
}
}
private void dirChecker(String dir) {
File f = new File(dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
And call using this,
Uri path = Uri.parse("file:///android_asset/kjv.zip");
inputPath = path.toString();
ZipManager zipManager = new ZipManager();
zipManager.unzip(inputPath, outputPath);
I tried, but it was error every time. Can't understand what is the problem. If you have alternative solution then please suggest me. Help me. Thank you.
Related
I am getting the "Zip Path Traversal Vulnerability" alert in Google Play Console.
I followed official Google docs (https://support.google.com/faqs/answer/9294009) to fix it but the alert is still there.
Here is the code that handles unzipping. I have even tested using a zip file that has the vulnerability described and the exception is raised as expected.
What am I missing?
private boolean unpackZip(File zipFile, File outputDirectory, IOnResult<Integer> progress) {
InputStream is;
ZipInputStream zis;
ZipInputStream zisCount;
try {
int totalEntries = 0;
int entryCount = 0;
String filename;
ZipEntry ze;
is = new FileInputStream(zipFile);
zisCount = new ZipInputStream(new BufferedInputStream(is));
while ((ze = zisCount.getNextEntry()) != null) {
// Fixing a Zip Path Traversal Vulnerability
// (https://support.google.com/faqs/answer/9294009)
filename = ze.getName();
File targetFile = new File(outputDirectory, filename);
String targetPath = targetFile.getCanonicalPath();
if (!targetPath.startsWith(outputDirectory.getCanonicalPath())) {
throw new SecurityException("Archive security error");
}
// -----------------------------------------------------------------------------
totalEntries++;
zisCount.closeEntry();
}
zisCount.close();
is = new FileInputStream(zipFile);
zis = new ZipInputStream(new BufferedInputStream(is));
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
// Fixing a Zip Path Traversal Vulnerability (https://support.google.com/faqs/answer/9294009)
File targetFile = new File(outputDirectory, filename);
String targetPath = targetFile.getCanonicalPath();
if (!targetPath.startsWith(outputDirectory.getCanonicalPath())) {
throw new SecurityException("Archive security error");
}
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
File fmd = new File(outputDirectory, filename);
fmd.mkdirs();
continue;
}
File outputFile = new File(outputDirectory, filename);
for( File parentFile = outputFile.getParentFile(); !parentFile.exists(); parentFile = parentFile.getParentFile() )
{
parentFile.mkdir();
}
FileOutputStream fout = new FileOutputStream(outputFile);
Log.d(TAG, "unzipped " + filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
entryCount++;
}
zis.close();
} catch (IOException | SecurityException e) {
Log.e(TAG, "unpackZip", e);
return false;
}
return true;
}
My Zipped folder contains sub-folder with files but while extracting it, I am not able to achieve the same hierarchy. I'm getting the unzipped structure as follows:-
/storage/emulated/0/unzipped_folder/sub_folder\main.png
/storage/emulated/0/unzipped_folder/sub_folder\test.xml
So while extracting it, I'm not able to get sub_folder as a directory.
I'm using below code while extracting the zip file.
public static void unzip(String zipFile, String location) throws IOException {
try {
File f = new File(location);
if (!f.isDirectory()) {
f.mkdirs();
}
ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile));
try {
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
String path = location + File.separator + ze.getName();
if (ze.isDirectory()) {
File unzipFile = new File(path);
if (!unzipFile.isDirectory()) {
unzipFile.mkdirs();
}
} else {
FileOutputStream fout = new FileOutputStream(path, false);
try {
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
} finally {
fout.close();
}
}
}
} finally {
zin.close();
}
} catch (Exception e) {
e.printStackTrace();
Log.e("ZIP STU", "Unzip exception", e);
}
}
Please help, I'm stuck in this for more than 2 days.
Thanks!
Finally I'm able to solve this issue using below code.
public static void unzipEPub(File zipFile, File destinationDir){
ZipFile zip = null;
try {
int DEFUALT_BUFFER = 1024;
destinationDir.mkdirs();
zip = new ZipFile(zipFile);
Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
while (zipFileEntries.hasMoreElements()) {
ZipEntry entry = zipFileEntries.nextElement();
String entryName = entry.getName();
entryName = entryName.replace("\\","/");
File destFile = new File(destinationDir, entryName);
File destinationParent = destFile.getParentFile();
if (destinationParent != null && !destinationParent.exists()) {
destinationParent.mkdirs();
}
if (!entry.isDirectory()) {
BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
int currentByte;
byte data[] = new byte[DEFUALT_BUFFER];
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos, DEFUALT_BUFFER);
while ((currentByte = is.read(data, 0, DEFUALT_BUFFER)) > 0) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
is.close();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (zip != null) {
try {
zip.close();
} catch (IOException ignored) {
}
}
}
}
I am trying to decompressing .zip, programmatically in my application with the help of this code,
public void unzip(String _zipFile, String _targetLocation) {
dirChecker(_targetLocation);
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_targetLocation + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
Log.i("xoxo", "unzip: completed!!!");
} catch (Exception e) {
Log.i("xoxo", "unzip: err: - " + e.toString());
}
}
Everything is fine, but the problem is I am getting an error,
java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor
While trying to decompress .zip created by server that is running on linux environment.
You can try this library
https://github.com/ankitdubey021/ExtractionLib
void extract(){
try {
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "value1.jar");
Extract.extract(outputFile, new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "extration").toString());
Toast.makeText(MainActivity.this, "Extracted!", Toast.LENGTH_SHORT).show();
}catch(Exception e){
System.out.println(e);
}}
It will easily extract your zip file. 3 years back I used it in a project. and still working.
I am downloading zip file from server to internal storage. And after downloading I want to unzip that file in internal storage itself. My file is downloaded to internal storage and I can see that but while unzip I am not able to read it. Below is my unzipfile() method. Can anyone tell where I am going wrong?
public void unzipfile()
{
try {
Log.d("unzipiing","unzipping");
ContextWrapper cw = new ContextWrapper(context);
String name_="foldername"; //Folder name in device android/data/
File directory = cw.getDir(name_, Context.MODE_PRIVATE);
File mypath=new File(directory,"dwnld");
FileOutputStream fout = new FileOutputStream(mypath);
File yourFile = new File(directory,"dwnld.zip");
Log.d("unzipiing","filepath -" + yourFile.getPath());
FileInputStream fin = new FileInputStream(yourFile.getPath());
ZipInputStream zin = new ZipInputStream(fin);
Log.d("unzipiing","zin size -" + zin.available());
// zin.available() give -1 in console log
BufferedInputStream in = new BufferedInputStream(zin);
BufferedOutputStream out = new BufferedOutputStream(fout);
byte b[] = new byte[zin.available()];
int n;
Log.d("unzip","n - " + in.read(b,0,1024));
while ((n = in.read(b,0,1024)) >= 0) {
out.write(b,0,n);
Log.d("unzip byte"," - " + n);
}
out.flush();
out.close();
in.close();
fin.close();
zin.close();
}
catch (Exception e){
}
}
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
use this method for unzip
public void unzip(String _zipFile, String _targetLocation) {
//create target location folder if not exist
dirChecker(_targetLocatioan);
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
//create dir if required while unzipping
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_targetLocation + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch (Exception e) {
System.out.println(e);
}
}
check the path
public void dirChecker(String filepath)
{
File file = new File(filePath);
if(file.exists())
//Do something
else
// Do something else.
}
There is an image file inside a directory. How to copy this image file into another directory that was just created ? The two directories are on the same internal storage of the device :)
You can use these functions. The first one will copy whole directory with all children or a single file if you pass in a file. The second one is only usefull for files and is called for each file in the first one.
Also note you need to have permissions to do that
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Functions:
public static void copyFileOrDirectory(String srcDir, String dstDir) {
try {
File src = new File(srcDir);
File dst = new File(dstDir, src.getName());
if (src.isDirectory()) {
String files[] = src.list();
int filesLength = files.length;
for (int i = 0; i < filesLength; i++) {
String src1 = (new File(src, files[i]).getPath());
String dst1 = dst.getPath();
copyFileOrDirectory(src1, dst1);
}
} else {
copyFile(src, dst);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.getParentFile().exists())
destFile.getParentFile().mkdirs();
if (!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
}
If you want to copy image programtically then use following code.
File sourceLocation= new File (sourcepath);
File targetLocation= new File (targetpath);
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
** Use FileUtils This Is Simple Fast And Best method and Download Jar file from here**
public void MoveFiles(String sourcepath) {
File source_f = new File(sourcepath);
String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsappStatus/yourfilename.mp4";
File destination = new File(destinationPath);
try
{
FileUtils.copyFile(source_f , destination);
}
catch (IOException e)
{
e.printStackTrace();
}
}
Go To Link For FileUtils Jar