How to download entire folder in java? - java

I want to download entire folder/directory from server.
The folder contain files. I tried it with zip functionality but for that i need to give path till the files and not the folder path.
like -
BufferedInputStream in = new BufferedInputStream(new FileInputStream("d:\\StoreFiles\\Temp\\profile.txt"));
I want something like ("d:\StoreFiles") which will download all the folders in Storefiles folder and the files inside the folder.
How can i implement this?

How about this? It recursively going in the directory and downloading:
public static void main(String[] args) {
directoryDownloader(new File("/Users/eugene/Desktop"));
}
private static void directoryDownloader(File input){
if(input.isDirectory()){
for(File file : input.listFiles()){
directoryDownloader(file);
}
} else {
downloadFile(input);
}
}
private static void downloadFile(File someFile){
System.out.println("Downloading file : " + someFile.getPath());
}
P.S. Implement the downloadFile how you want.

I would suggest looking at Apache Commons IO FileUtils to copy directories. It's pretty easy to use. Have a look at the javadoc
Some of the useful methods that might come in handy (note that there are several ones available):
copyDirectory(File srcDir, File destDir)
copyDirectory(File srcDir, File destDir, FileFilter filter)

I think this example useful for u
public class CopyDirectoryExample
{
public static void main(String[] args)
{
File srcFolder = new File("c:\\mkyong");
File destFolder = new File("c:\\mkyong-new");
//make sure source exists
if(!srcFolder.exists()){
System.out.println("Directory does not exist.");
//just exit
System.exit(0);
}else{
try{
copyFolder(srcFolder,destFolder);
}catch(IOException e){
e.printStackTrace();
//error, just exit
System.exit(0);
}
}
System.out.println("Done");
}
public static void copyFolder(File src, File dest)
throws IOException{
if(src.isDirectory()){
//if directory not exists, create it
if(!dest.exists()){
dest.mkdir();
System.out.println("Directory copied from "
+ src + " to " + dest);
}
//list all the directory contents
String files[] = src.list();
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
copyFolder(srcFile,destFile);
}
}else{
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
System.out.println("File copied from " + src + " to " + dest);
}
}
}

Related

Zip file is created with windows path separator

I create a zip file using below code. Zip is created properly, then later in my program I try to get a zip entry from this file. And if I print a zip entry name I get windows path separators(Eg \a\b\c). But I need this like a/b/c. I have not posted reading zip entry code.
public static void zipFolder(File subdirs, String ZipName) throws FileNotFoundException, IOException {
try (FileOutputStream fileWriter = new FileOutputStream(location+File.seperator+ ZipName);
ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
addFolderToZip(subdirs, subdirs, zip);
}
}
private static void addFileToZip(File rootPath, File srcFile, ZipOutputStream zip) throws FileNotFoundException, IOException {
if (srcFile.isDirectory()) {
addFolderToZip(rootPath, srcFile, zip);
} else {
byte[] buf = new byte[1024];
int len;
try (FileInputStream in = new FileInputStream(srcFile)) {
String name = srcFile.getPath();
name = name.replace(rootPath.getPath() + File.separator, "");
zip.putNextEntry(new ZipEntry(name));
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
}
}
}
private static void addFolderToZip(File rootPath, File srcFolder, ZipOutputStream zip) throws FileNotFoundException, IOException {
for (File fileName : srcFolder.listFiles()) {
addFileToZip(rootPath, fileName, zip);
}
}
The root cause of your problem in the following snippet:
String name = srcFile.getPath();
name = name.replace(rootPath.getPath() + File.separator, "");
zip.putNextEntry(new ZipEntry(name));
The File.getPath() method returns the path with the system-dependent default name-separator.
So, according to this
Within a ZIP file, pathnames use the forward slash / as separator, as required by the ZIP spec (4.4.17.1). This requires a conversion from or to the local file.separator on systems like Windows. The API (ZipEntry) does not take care of the transformation, and the need for the programmer to deal with it is not documented.
you should rewrite this snippet in the following way:
String name = srcFile.getPath();
name = name.replace(rootPath.getPath() + File.separator, "");
if (File.separatorChar != '/') {
name = name.replace('\\', '/');
}
zip.putNextEntry(new ZipEntry(name));

FileNotFoundException when using FileOutputStream

I need to extract tar file by this code.
But it' this error when I use FileOutputStream(outputFile);
" java.io.FileNotFoundException: D:\TestFile\1.png (Access is denied)"
Input is 1.tar file from Drive D:/testFile
and extract to same folder
I try check path of outputfile by outputFile.getCanonicalFile but it's ok!!
what wrong?
public class DecompressTarFile {
public ArrayList<File> getTarFileExtracted() {
return tarFileExtracted;
}
public ArrayList<File> tarFileExtracted = new ArrayList<File>();
public DecompressTarFile(File inputFile, File outputDir) throws FileNotFoundException, ArchiveException, IOException {
System.out.println("Untaring " + inputFile.getAbsolutePath() + " to dir " + outputDir.getAbsolutePath() + ".");
InputStream inputStream = new FileInputStream(inputFile);
TarArchiveInputStream tarStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", inputStream);
TarArchiveEntry tarEntry = null;
while ((tarEntry = (TarArchiveEntry) tarStream.getNextEntry()) != null) {
File outputFile = new File(outputDir, tarEntry.getName());
System.out.println("Attempting to write output directory " + outputFile.getAbsolutePath());
if (!outputFile.exists()) {
System.out.println("Attempting to create output directory " + outputFile.getAbsolutePath());
if (!outputFile.mkdirs()) {
throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
}
} else {
System.out.println("Create output file " + outputFile.getAbsolutePath());
OutputStream outputFileStream = new FileOutputStream(outputFile);
IOUtils.copy(tarStream, outputFileStream);
outputFileStream.close();
}
tarFileExtracted.add(outputFile);
}
tarStream.close();
}
}
and called by main class
static File tarFileInput = new File("D:/TestFile/haha.tar");
static File tarPathFileOutput = new File("D:/TestFile");
public static void main(String[] args) throws ArchiveException, IOException {
decomp = new DecompressTarFile(tarFileInput, tarPathFileOutput);
//listOutput = decomp.getTarFileExtracted();
}
And this result from this code
run:
Untaring D:\TestFile\haha.tar to dir D:\TestFile.
Attempting to write output directory D:\TestFile\1.png
Create output file D:\TestFile\1.png
Exception in thread "main" java.io.FileNotFoundException: D:\TestFile\1.png (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at com.service..TarFile.DecompressTarFile.<init>(DecompressTarFile.java:53)
at com.service..TarFile.MainForTest.main(MainForTest.java:28)
Java Result: 1
This is the problem:
Attempting to write output directory D:\TestFile\1.png
You've created the target filename as a directory. You need to separate out "the directory I need to exist" and "the file I want to write to". For example:
File outputFile = new File(outputDir, tarEntry.getName());
File outputDirectory = outputFile.getParent();
if (!outputDirectory.exists()) {
// Try to create the directory
}
Oh, and also you've got a loop condition of:
while (tarEntry != null)
... but you're not changing the value of tarEntry in the loop...

Corrupted docx generated using zipping

Let me just start out by saying I created an account on here because I've been beating my head against a wall in order to try and figure this out, so here it goes.
Also, I have already seen this question here. Neither one of those answers have helped and I have tried both of them.
I need to create a word document with a simple table and data inside. I decided to create a sample document in which to get the xml that I need to create the document. I moved all the folders from the unzipped docx file into my assets folder. Once I realized I couldn't write to the assets folder, I wrote a method to copy all the files and folders over to an external storage location of the device and then write the document I created to the same location. From there Im trying to zip the files back up to a .docx file. This is where things arent working.
The actual docx file is created and I can move it to my computer through the DDMS but when I go to view it Word says its corrupt. Heres whats weird though, if I unzip it and then rezip it on my computer without making any changes what so ever it works perfectly. I have used a program (for mac) called DiffMerge to compare the sample unzipped docx file to the unzipped docx that I have created and it says they are exactly the same. So, I think it has something to do with the zipping process in Android.
I have also tried unzipping the sample docx file on my computer, moving all the files and folders over to my assets folder including the document.xml file and just try to zip it up without adding my own document.xml file and using the sample one and that doesnt work either. Another thing I tried was to place the actual docx file in my assets folder, unzipping it onto my external storage and then rezipping it without doing anything. This also fails.
I'm basically at a loss. Please somebody help me figure this out.
Here is some of my code:
moveDocxFoldersFromAssetsToExternalStorage() is called first.
After that is called all the files have been moved over.
Then, I create the document.xml file and place it in the word directory where it belongs
Everything is where it should be and I now try to create the zip file.
.
private boolean moveDocxFoldersFromAssetsToExternalStorage(){
File rootDir = new File(this.externalPath);
rootDir.mkdir();
copy("");
// This is to get around a glitch in Android which doesnt list files or folders
// with an underscore at the beginning of the name in the assets folder.
// This renames them once they are saved to the device.
// We need it to show up in the list in order to move them.
File relsDir = new File(this.externalPath + "/word/rels");
File renameDir = new File(this.externalPath + "/word/_rels");
relsDir.renameTo(renameDir);
relsDir = new File(this.externalPath + "/rels");
renameDir = new File(this.externalPath + "/_rels");
relsDir.renameTo(renameDir);
// This is to get around a glitch in Android which doesnt list hidden files.
// We need it to show up in the list in order to move it.
relsDir = new File(this.externalPath + "/_rels/rels.rename");
renameDir = new File(this.externalPath + "/_rels/.rels");
relsDir.renameTo(renameDir);
return true;
}
private void copy(String outFileRelativePath){
String files[] = null;
try {
files = this.mAssetManager.list(ASSETS_RELATIVE_PATH + outFileRelativePath);
} catch (IOException e) {
e.printStackTrace();
}
String assetFilePath = null;
for(String fileName : files){
if(!fileName.contains(".")){
String outFile = outFileRelativePath + java.io.File.separator + fileName;
copy(outFile);
} else {
File createFile = new File(this.externalPath + java.io.File.separator + outFileRelativePath);
createFile.mkdir();
File file = new File(createFile, fileName);
assetFilePath =
ASSETS_RELATIVE_PATH + outFileRelativePath + java.io.File.separator + fileName;
InputStream in = null;
OutputStream out = null;
try {
in = this.mAssetManager.open(assetFilePath);
out = new FileOutputStream(file);
copyFile(in, out);
in.close();
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
private void zipFolder(String srcFolder, String destZipFile) throws Exception{
FileOutputStream fileWriter = new FileOutputStream(destZipFile);
ZipOutputStream zip = new ZipOutputStream(fileWriter);
zip.setMethod(Deflater.DEFLATED);
zip.setLevel(ZipOutputStream.STORED);
addFolderToZip(this.externalPath, "", zip);
zip.finish();
zip.close();
}
private void addFolderToZip(String externalPath, String folder, ZipOutputStream zip){
File file = new File(externalPath);
String files[] = file.list();
for(String fileName : files){
try {
File currentFile = new File(externalPath, fileName);
if(currentFile.isDirectory()){
String outFile = externalPath + java.io.File.separator + fileName;
addFolderToZip(outFile, folder + java.io.File.separator + fileName, zip);
} else {
byte[] buffer = new byte[8000];
int len;
FileInputStream in = new FileInputStream(currentFile);
zip.putNextEntry(new ZipEntry(folder + java.io.File.separator + fileName));
while((len = in.read(buffer)) > 0){
zip.write(buffer, 0, len);
}
zip.closeEntry();
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
EDIT
Here is the code I wrote in order to get it working correctly based on what #edi9999 said below. I created a separate class that Im going to expand and add to and probably clean up a bit but this is working code. It adds all the files in a directory to the zip file and recursively calls itself to add all the subfiles and folders.
private class Zip {
private ZipOutputStream mZipOutputStream;
private String pathToZipDestination;
private String pathToFilesToZip;
public Zip(String pathToZipDestination, String pathToFilesToZip) {
this.pathToZipDestination = pathToZipDestination;
this.pathToFilesToZip = pathToFilesToZip;
}
public void zipFiles() throws Exception{
FileOutputStream fileWriter = new FileOutputStream(pathToZipDestination);
this.mZipOutputStream = new ZipOutputStream(fileWriter);
this.mZipOutputStream.setMethod(Deflater.DEFLATED);
this.mZipOutputStream.setLevel(8);
AddFilesToZip("");
this.mZipOutputStream.finish();
this.mZipOutputStream.close();
}
private void AddFilesToZip(String folder){
File mFile = new File(pathToFilesToZip + java.io.File.separator + folder);
String mFiles[] = mFile.list();
for(String fileName : mFiles){
File currentFile;
if(folder != "")
currentFile = new File(pathToFilesToZip, folder + java.io.File.separator + fileName);
else
currentFile = new File(pathToFilesToZip, fileName);
if(currentFile.isDirectory()){
if(folder != "")
AddFilesToZip(folder + java.io.File.separator + currentFile.getName());
else
AddFilesToZip(currentFile.getName());
} else {
try{
byte[] buffer = new byte[8000];
int len;
FileInputStream in = new FileInputStream(currentFile);
if(folder != ""){
mZipOutputStream.putNextEntry(new ZipEntry(folder + java.io.File.separator + fileName));
} else {
mZipOutputStream.putNextEntry(new ZipEntry(fileName));
}
while((len = in.read(buffer)) > 0){
mZipOutputStream.write(buffer, 0, len);
}
mZipOutputStream.closeEntry();
in.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
}
I think I've got what's wrong.
When I opened your corrupted File, and opened it on winrar, I saw antislashes at the beginning of the folders, which is unusual:
When I rezip the file after unzipping it, the antislashes are not there anymore and the file opens in Word so I think it should be the issue.
I think the code is wrong here:
String outFile = externalPath + java.io.File.separator + fileName;
should be
if (externalPath=="")
String outFile = externalPath + fileName;
else
String outFile = externalPath + java.io.File.separator + fileName;

Java: Maintaining zipped files Modified Date

A proprietary program that I'm working with zips up and extracts certain files without changing the modified date of the files when unzipping. I'm also creating my own zip and extraction tool based off the source code in our program but when I'm unzipping the files the modified date of all zipped files is showing with the unzip time & date. Here's the code for my extraction:
public static int unzipFiles(File zipFile, File extractDir) throws Exception
{
int totalFileCount = 0;
String zipFilePath = zipFile.getPath();
System.out.println("Zip File Path: " + zipFilePath);
ZipFile zfile = new ZipFile(zipFile);
System.out.println("Size of ZipFile: "+zfile.size());
Enumeration<? extends ZipEntry> entries = zfile.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
System.out.println("ZipEntry File: " + entry.getName());
File file = new File(extractDir, entry.getName());
if (entry.isDirectory())
{
System.out.println("Creating Directory");
file.mkdirs();
}
else
{
file.getParentFile().mkdirs();
InputStream in = zfile.getInputStream(entry);
try
{
copy(in, file);
}
finally
{
in.close();
}
}
totalFileCount++;
}
return totalFileCount;
}
private static void copy(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
System.out.println("InputStream/OutputStram copy");
while (true)
{
int readCount = in.read(buffer);
if (readCount < 0)
{
break;
}
out.write(buffer, 0, readCount);
}
}
I'm sure there is a better way to do this other than doing the inputstream/outputstream copy. I'm sure this is the culprit as doing an extraction with winRAR does not change the date with the files I zipped.
Use ZipEntry.getTime to get the last-modified time and File.setLastModified to set it on the file after you are done copying it.

Recursively ZIP a directory containing any number of files and subdirectories in Java?

Is there an easy way to recursively ZIP a directory that may or may not contain any number of files and any number of levels of subdirectories?
public final class ZipFileUtil {
public static void zipDirectory(File dir, File zipFile) throws IOException {
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
zipSubDirectory("", dir, zout);
zout.close();
}
private static void zipSubDirectory(String basePath, File dir, ZipOutputStream zout) throws IOException {
byte[] buffer = new byte[4096];
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
String path = basePath + file.getName() + "/";
zout.putNextEntry(new ZipEntry(path));
zipSubDirectory(path, file, zout);
zout.closeEntry();
} else {
FileInputStream fin = new FileInputStream(file);
zout.putNextEntry(new ZipEntry(basePath + file.getName()));
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
}
}
}
You can use the Java API Specification
and How do you recursively traverse through file folders?.
I use the ZipFileSystem implementation in ruby with great success, though I've never used it in java. You might want to check this out:

Categories

Resources