Empty Folders are not adding to zip file android - android

I am doing an Android project. I need to zip a complete folder structure of SD card.
code is able to zip the folder if any files exists inside the folder, else skips that folder.
My Folder structure is like: mnt/sdcard/Movies/Telugu/Files.
mnt/sdcard/Movies/English --> English is empty folder
I did not see English folder in output zip file.
My code:
public void zip() {
try {
// create a ZipOutputStream to zip the data to
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(
_zipFile));
zipDir(folderPath, zos);
// close the stream
zos.close();
} catch (Exception e) {
// handle exception
}
}
public void zipDir(String dir2zip, ZipOutputStream zos) {
try {
File zipDir = new File(dir2zip);
// get a listing of the directory content
String[] dirList = zipDir.list();
byte[] readBuffer = new byte[2156];
int bytesIn = 0;
// loop through dirList, and zip the files
for (int i = 0; i < dirList.length; i++) {
File f = new File(zipDir, dirList[i]);
if (f.isDirectory()) {
// if the File object is a directory, call this
// function again to add its content recursively
String filePath = f.getPath();
zipDir(filePath, zos);
// loop again
continue;
}
// if we reached here, the File object f was not a directory
// create a FileInputStream on top of f
FileInputStream fis = new FileInputStream(f);
// create a new zip entry
ZipEntry anEntry = new ZipEntry(f.getPath());
// place the zip entry in the ZipOutputStream object
zos.putNextEntry(anEntry);
// now write the content of the file to the ZipOutputStream
while ((bytesIn = fis.read(readBuffer)) != -1) {
zos.write(readBuffer, 0, bytesIn);
}
// close the Stream
fis.close();
}
} catch (Exception e) {
e.printStackTrace();
// handle exception
}
}
Please help..

You basically never create a zipentry for your directories.
In the if (f.isDirectory()) {} section, add this:
zos.putNextEntry(new ZipEntry(filePath));
You can also put it at the beginning of the method instead, to include the root dir as well.

It's old post but it will be good for who searching to solve problem.
You have just add dirName+"/", Yes you need just one slash to end of folder name string.
if(dirList.length==0){
String path=zipDir.getPath().replace(rootDir,"");
ZipEntry anEntry = new ZipEntry(path+"/");
zos.putNextEntry(anEntry);
}

Related

Android unzip open failed: ENOENT (No such file or directory)

I am using the following code to unzip a set of files (containing folders as well):
private boolean unpackZip(String path, String zipname)
{
InputStream is;
ZipInputStream zis;
try
{
String filename;
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null)
{
// zapis do souboru
filename = ze.getName();
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
File fmd = new File(path + filename);
fmd.mkdirs();
continue;
}
FileOutputStream fout = new FileOutputStream(path + filename);
// cteni zipu a zapis
while ((count = zis.read(buffer)) != -1)
{
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
}
catch(IOException e)
{
e.printStackTrace();
return false;
}
return true;
}
The code fails on FileOutputStream fout = new FileOutputStream(path + filename) with the error:
java.io.FileNotFoundException: /storage/emulated/0/BASEFOLDER/FOLDER1/FILE.png
BASEFOLDER already exists, that is where I am trying to unzip the folder to. If I manually (or programmatically) create FOLDER1, the code runs fine and successfully unzips. I believe it is crashing because the very first file (ze) is named FOLDER1/FILE.png and FOLDER1 hasn't been created yet. How do I get around this? I know other people have used this code, I find it unlikely that it randomly doesn't work for me...
Have you got this in your AndroidManifest.xml file?
Add Write to external Storage permission
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
I had the same problem. After several investigation I found that. put following single line in your code:
if (ze.isDirectory()) {
File fmd = new File(path + filename);
fmd.mkdirs();
zis.closeEntry(); // <<<<<< ADD THIS LINE
continue;
}
Sometime the extract files has been extracted before its parent directory is created, for example:
File A inside directory B. But B directory is not created, index of files listing below cause the issue:
dir_b/file_a.txt
dir_b/
dir_b/file_c.txt
So, to sure directory created before file extracting, you need to create parent directories first, for example:
val targetFile = File(tempOutputDir, zipEntry.name)
if (zipEntry.isDirectory) {
targetFile.mkdirs()
} else {
try {
try {
targetFile.parentFile?.mkdirs() // <-- ADD THIS LINE
} catch (exception: Exception) {
Log.e("ExampleApp", exception.localizedMessage, exception)
}
val bufferOutputStream = BufferedOutputStream(
FileOutputStream(targetFile)
)
val buffer = ByteArray(1024)
var read = zipInputStream.read(buffer)
while (read != -1) {
bufferOutputStream.write(buffer, 0, read)
read = zipInputStream.read(buffer)
}
bufferOutputStream.close()
} catch (exception: Exception) {
Log.e("ExampleApp", exception.localizedMessage, exception)
}
}

move video file from /mnt/sdcard to /mnt/extsd

I am trying to move file from /mnt/sdcard to /mnt/extsd
Currently file is stored in /mnt/sdcard/DCIM/camera after shooting a video
but now i want to move this file to /mnt/extsd
I am using following code
File fromFile=new File( "/mnt/sdcard/folderpath" ,"/video.mp4");
File toFile=new File("/mnt/extsd" ,fromFile.getName());
fromFile.renameTo(toFile);
I read that renameTo dosen't work for moving in different file systems
Please help me
 try {
  java.io.FileInputStream fosfrom = new java.io.FileInputStream(fromFile);
  java.io.FileOutputStream fosto = new FileOutputStream(toFile);
  byte bt[] = new byte[1024];
  int c;
  while ((c = fosfrom.read(bt)) > 0) {
  fosto.write(bt, 0, c); //将内容写到新文件当中
  }
  fosfrom.close();
  fosto.close();
  } catch (Exception ex) {
  Log.e("readfile", ex.getMessage());
  }
  }
give source file where exist ur file and target location where u want to store .
public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < sourceLocation.listFiles().length; i++) {
copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
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();
}
}
according to Android docs "Both paths must be on the same mount point" like it could be used for file renaming only in case of different paths. So if you want to move it you probably should copy it and then rename and then delete the source file. But in this case you are trying not only to move the file from one FS to another but also you are trying to use /mnt/extsd which might not be able at all. Follow this question about such paths.

How to compress a folder to make docx file in android?

I'm trying to make an Android application that can open a docx file to read, edit and save it.
My idea is to extract all the xml file within the archive to a temp folder. In this folder we can edit the content of the docx in /word/document.xml. The problem is when I compress this temp folder to make a new docx file and replace the old file, inside the new docx archive the path is like /mnt/sdcard/temp/"all files xml go here" while the xml files should be in the first level.
Can anybody help me to go through this? here is the method to compress the temp directory
Note: dir2zip argument's value I use is /mnt/sdcard/temp/***.docx
public void zipDir(String dir2zip, ZipOutputStream zos)
{
try
{
//create a new File object based on the directory we
//have to zip File
File zipDir = new File(dir2zip);
//get a listing of the directory content
String[] dirList = zipDir.list();
byte[] readBuffer = new byte[2156];
int bytesIn = 0;
//loop through dirList, and zip the files
for(int i=0; i<dirList.length; i++)
{
File f = new File(zipDir, dirList[i]);
if(f.isDirectory())
{
//if the File object is a directory, call this
//function again to add its content recursively
String filePath = f.getPath();
zipDir(filePath, zos);
//loop again
continue;
}
//if we reached here, the File object f was not a directory
//create a FileInputStream on top of f
FileInputStream fis = new FileInputStream(f);
//create a new zip entry
ZipEntry anEntry = new ZipEntry(f.getPath());
//place the zip entry in the ZipOutputStream object
zos.putNextEntry(anEntry);
//now write the content of the file to the ZipOutputStream
while((bytesIn = fis.read(readBuffer)) != -1)
{
zos.write(readBuffer, 0, bytesIn);
}
//close the Stream
fis.close();
}
}
catch(Exception e)
{
//handle exception
}
}
I have managed to fix it by myself. The problem is in this line:
File f = new File(zipDir, dirList[i]);
It should be
File f = new File(dirList[i]);
If the argument zipDir is included, the absolute path to the directory will be used in the archive!
I have now managed to get the original poster's code working on Mac and Windows by making the following two modifications:
1: add a ZipEntry for each directory: do not simply ignore it
2: remove the directory name from the ZipEntry name
Note: zipinfo is useful
This is a program that works for me:
import java.io.*;
import java.util.zip.*;
public class zipdoc
{
String savedDir = null;
public void zipDir(String dir2zip, ZipOutputStream zos)
{
try
{
if (savedDir == null)
savedDir = dir2zip;
// create a new File object based on the directory we
// have to zip File
File zipDir = new File(dir2zip);
//get a listing of the directory content
String[] dirList = zipDir.list();
byte[] readBuffer = new byte[2156];
int bytesIn = 0;
// loop through dirList, and zip the files
for (int i=0; i<dirList.length; i++)
{
File f = new File(zipDir, dirList[i]);
if (f.isDirectory())
{
// if the File object is a directory, call this
// function again to add its content recursively
System.out.println("Adding dir: " + f);
// create a new zip entry
ZipEntry anEntry = new ZipEntry(f.getPath().substring(savedDir.length()+1) + "/");
// place the zip entry in the ZipOutputStream object
zos.putNextEntry(anEntry);
String filePath = f.getPath();
zipDir(filePath, zos);
// loop again
continue;
}
else if (!f.getName().equals(".DS_Store"))
{
// if we reached here, the File object f was not a directory
// and it's not the MacOSX special .DS_Store
// create a FileInputStream on top of f
System.out.println("Adding file: " + f);
FileInputStream fis = new FileInputStream(f);
// create a new zip entry
ZipEntry anEntry = new ZipEntry(f.getPath().substring(savedDir.length()+1));
// place the zip entry in the ZipOutputStream object
zos.putNextEntry(anEntry);
// now write the content of the file to the ZipOutputStream
while((bytesIn = fis.read(readBuffer)) != -1)
{
zos.write(readBuffer, 0, bytesIn);
}
// close the Stream
fis.close();
}
}
}
catch(Exception e)
{
// handle exception
System.out.println(e);
}
}
public void zipit(String inDir, String outFile)
{
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(outFile)));
zos.setMethod(0);
zos.setMethod(ZipOutputStream.DEFLATED);
zos.setLevel(0);
zipDir(inDir, zos);
zos.finish();
zos.close();
}
catch (Exception e)
{
System.out.println(e);
}
}
public static void main (String args[]) {
zipdoc z1 = new zipdoc();
// Check there are sufficient params if desired
// first param is directory to be 'zipped', second is resulting
// filename (??.docx)
// eg java zipdoc dir1 newDoc.docx
z1.zipit(args[0], args[1]);
System.out.println("Finished creating " + args[1]);
}
}

How to load the local html page using intent in Android?

I have a html file in my asset directory and i have to load it as browser application using Intent.
Here is my code, but its not working:
startActivity (new Intent(Intent.ACTION_VIEW,
Uri.parse("file:///android_asset/Sample.htm")));
Could anyone help me?
Use loadUrl() method of WebView to load an html page
Sample Example
if faq.html is the html file present in assets folder then you can use
WebView html = (WebView) findViewById(R.id.webEulaView);
html.loadUrl("file:///android_asset/faq.html");
i had the same problem what i did was
copied the content of the assets to a database and then pulled it from the sdcard
here is the code to copy your assets to sdcard
the logic used is as follows the html pages are put in the zip file in assets folder
content is the name of the zip in assets folder
boolean succussFlag = false;
destination="";
destination=Environment.getExternalStorageDirectory()+"/";
File file = new File(destination);
if (!file.exists()){
file.mkdirs();
}
else
{
//file.delete();
//file.mkdir();
}
try
{
InputStream fileInput = context.getAssets().open("content.zip");
ZipInputStream inputStream = new ZipInputStream(fileInput);
for (ZipEntry entry = inputStream.getNextEntry(); entry != null; entry = inputStream.getNextEntry())
{
String innerFileName = destination + entry.getName();
System.out.println("destination::::"+innerFileName);
// Log.v("inner file name 0",""+innerFileName);
File innerFile = new File(innerFileName);
if (innerFile.exists())
{
innerFile.delete();
}
// Check if it is a folder
if (entry.isDirectory())
{
// Its a folder, create that folder
innerFile.mkdirs();
}
else
{
// System.out.println(" ::::::::::::::INNER FILE COPYING :::: " + innerFile.toString());
FileOutputStream outputStream = new FileOutputStream(innerFileName);
final int BUFFER = 4096;
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream,
BUFFER);
int count = 0;
byte[] data = new byte[BUFFER];
while ((count = inputStream.read(data, 0, BUFFER)) != -1)
{
bufferedOutputStream.write(data, 0, count);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
inputStream.closeEntry();
}
inputStream.close();
// System.out.println(" ::::::::::COPIED TO PRIVATE FOLDER :::: " );
succussFlag=true;
}
catch (IOException e)
{
// System.out.println("** EXCEPTION OCCURED WHILE COPYING***");
e.printStackTrace();
succussFlag=false;
}
return succussFlag;
after this you give following command
startActivity (new Intent(Intent.ACTION_VIEW,"file://"+ Environment.getExternalStorageDirectory()+"/content"+name_Html ;
);

How to zip the files in android

I have a requirement to zip the text files programatically.
I have created text files at files directory(context.getFilesDirectory()),
I want zip the text files and add the zipped file to the Intent object.
Please provide me a piece of code to how to zip the files in android.
If you have a FOLDER in SDCard and you want to create a zip of it, then simply copy and paste this code in your project and it will give you a zip Folder. This code will create a zip of the folder which only contains files no nested folder should be inside. You can further modify for your self.
String []s=new String[2]; //declare an array for storing the files i.e the path of your source files
s[0]="/mnt/sdcard/Wallpaper/pic.jpg"; //Type the path of the files in here
s[1]="/mnt/sdcard/Wallpaper/Final.pdf"; // path of the second file
zip((s,"/mnt/sdcard/MyZipFolder.zip"); //call the zip function
public void zip(String[] files, String zipFile)
{
private String[] _files= files;
private String _zipFile= zipFile;
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
for(int i=0; i < _files.length; i++) {
Log.d("add:",_files[i]);
Log.v("Compress", "Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
Also add permissions in android-manifest.xml using this code
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
If you want to compress files with password you can take a look at this library you need to add this lines to your build.gradle:
dependencies {
compile 'com.github.ghost1372:Mzip-Android:0.4.0'
}
here is the code to zip files:
Zip:
ZipArchive zipArchive = new ZipArchive();
zipArchive.zip(targetPath,destinationPath,password);
//This Library is dead as it is not avaialable on github anymore
This is working code for zipping the files. You have to add all the file paths which you want to zip into the arrayList and send it as parameter to below function along with string name for zipfile you want.
public String zipper(ArrayList<String> allFiles, String zipFileName) throws IOException
{
timeStampOfZipFile =new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime());
App.mediaStorageDir.mkdirs();
zippath = App.mediaStorageDir.getAbsolutePath() + "/" + zipFileName+ timeStampOfZipFile + ".zip";
try
{
if (new File(zippath).exists())
{
new File(zippath).delete();
}
//new File(zipFileName).delete(); // Delete if exists
ZipFile zipFile = new ZipFile(zippath);
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
zipParameters.setPassword("Reset");
if (allFiles.size() > 0)
{
for (String fileName : allFiles)
{
File file = new File(fileName);
zipFile.addFile(file, zipParameters);
}
}
}
catch (ZipException e)
{
e.printStackTrace();
}
return zippath;
}
Here App.mediaStorageDir.mkdirs();
where mediaStorage is static final string in my App.class
public static final File mediaStorageDir = new File(Environment.getExternalStorageDirectory(),
"yourAppFoler");
creates directory where the zip file will be saved. Result of function returns zip file path which can be used to attach to multipart entity for sending it to server(if you wish).
Requires run time permission for API>=marshmellow
<!-- == External Storage == -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Categories

Resources