Why doesn't cant it copy folders and only does files - java

I have a method that takes source address, destination address and an ArrayList, then it goes through the giver Source folder and check each file with the ArrayList items and if they have the same name, then it copies the the destination with the exact same folder structure (so it makes folders in needed). All works till here. But it gives error if the item of the ArrayList is a folder name. Some how It can't find that folder, and comes up with errors.
Here is my code:
public class Syncer {
public static void main(String[] args) {
File source = new File("D:\\Documents\\A X");
File destination = new File("D:\\Documents\\A X Sample");
ArrayList<String> list = new ArrayList<String>();
list.add("third");
folderCrawler(source, destination, list);
}
public static void folderCrawler(File src, File dest, ArrayList<String> filesToCopy){
if(src.isDirectory()){
String[] children = src.list();
for(String file:children){
if(filesToCopy.contains(file)){
File from = new File(src, file);
File to = new File(dest, file);
dest.mkdirs();
try{
copy(from, to);
}catch(IOException e){
e.printStackTrace();
System.exit(0);
}
}
else{System.out.println("Not Found");}
}
for (int i=0; i<children.length; i++){
folderCrawler(new File(src, children[i]), new File(dest, children[i]), filesToCopy);
}
}
}
public static void copy(File src, File dest) throws IOException{
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
System.out.println("Copied: " + src.getName());
in.close();
out.close();
}
}
It does compile and goes down the list till it finds the array item same as the current source, and then stops.
Error:
java.io.FileNotFoundException: D:\Documents\A X\folder2\tohi\third (Access is denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at syncer.Syncer.copy(Syncer.java:61)
at syncer.Syncer.folderCrawler(Syncer.java:45)
at syncer.Syncer.folderCrawler(Syncer.java:55)
at syncer.Syncer.folderCrawler(Syncer.java:55)
at syncer.Syncer.main(Syncer.java:31)
In my other mathchine I get same error but it is (Is a directory) instead of (Access denied).
So any idea to make it work even if a folder is given. So it will copy the folder with its inner files ?

Sorry, I don' have enough rep to comment.
Have a look at apache commons FileUtils. They have a lot of copy functions so you don't have to implement them yourself.

Related

copy files and directory in java

In my program I suppose to copy a directory to another directory with java. I did it but the only problem is that for the directories that are inside the source directory get copied but not the file inside them. Why?
This is the assigment:
Ask the user for the source directory and a destination. The source is the directory to be copied; the destination is the directory that will be the parent of the new copy.
First your program should make a new directory in the new location with the same name as the source directory. (You may need to do something special for root directories if you are copying an entire disk. A root directory has no parent directory, and often, no name.)
Then your program should create an array with File class objects for each item in the contents of the source directory, similar to what was done in DirectoryListDemo.
Next , it should iterate the array, and for each item in the array,
if it is a file, copy the file to the new directory using the copyFile() method taken from CopyFileDemoE.
if it is a directory, recursively call this method to copy the directory and all of its contents.
Here is the code:
package com.company;
import java.io.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
Scanner src = new Scanner(System.in);
System.out.println("Enter name of source directory to copy from: ");
String sourceFile= src.nextLine();
System.out.println("Enter name of destination directory to copy the files into: ");
String destinationFile = (src.nextLine()+"/"+sourceFile);
isDirFile(sourceFile, destinationFile);
}
public static void isDirFile(String source, String dest) throws Exception{
File sourceFile = new File ("C:/"+source);
File dirFile = new File (dest, new File(source).getName());
dirFile.mkdirs();
File[] entries;
if (dirFile.exists()){
if (sourceFile.isDirectory()){
entries = sourceFile.listFiles();
assert entries != null;
for (File entry:entries){
if(entry.isFile()){
copyFile(entry.getAbsolutePath(),dest);
}
else{
isDirFile(entry.getAbsolutePath(),dest);
}
}
}
}
else{
System.out.println("File does not exist");
}
}
public static void copyFile(String source, String destination) throws Exception{
File sourceFile;
File destFile;
FileInputStream sourceStream;
FileOutputStream destSteam;
BufferedInputStream bufferedSource = null;
BufferedOutputStream bufferedDestination = null;
try{
sourceFile = new File(source);
destFile = new File (destination, new File(source).getName());
sourceStream = new FileInputStream(sourceFile);
destSteam = new FileOutputStream(destFile);
bufferedSource = new BufferedInputStream(sourceStream, 8182);
bufferedDestination = new BufferedOutputStream(destSteam, 8182);
int transfer;
System.out.println("Beginning file copy: ");
System.out.println("\tcopying "+ source);
System.out.println("\tto "+destination);
while ((transfer = bufferedSource.read()) != -1){
bufferedDestination.write(transfer);
}
}
catch (IOException e){
e.printStackTrace();
System.out.println(" An unexpected I/O error occurred.");
}
finally {
if(bufferedSource != null){
bufferedSource.close();
}
if(bufferedDestination != null){
bufferedDestination.close();
}
System.out.println("Files closed. Copy complete.");
}
}
}

Why does copying the contents of a folder takes a lot of time in java

I wrote a code in java to copy directories using streams. The working is good, all the files are getting copied to their appropriate locations. However, the program takes a lot of time to terminate even after copying the last remaining file in the directory. I just wanted to know that is it normal or do i have to make some changes in my code. here is the code that i wrote:
void copy_file(File source, File dest){
File temp_file = new File(dest.getPath()+File.separator+source.getName());
if(!temp_file.exists()){
temp_file.mkdir();
}
File[] list = source.listFiles();
if(list.length>0){
for(File temp:list){
if(temp.isFile()){
copy(temp, temp_file);
}
else{
copy_file(temp, temp_file);
}
}
}
}
void copy(File source, File dest){
System.out.print("\n Copying File: "+source.getName());
try(FileInputStream fin = new FileInputStream(source);
FileOutputStream fout = new FileOutputStream(dest.getPath()+File.separator+source.getName())){
byte[] buffer = new byte[1024];
int length;
while((length = fin.read(buffer)) > 0){
fout.write(buffer, 0, buffer.length);
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}

Copying saved files from a List<File> into a directory recursively in java

I have searched for this answer and I have tried to solve the problem but I can't. I got and Exception of type
No fue posible copiar los archivos. Motivo: C:\Test1 (Acceso denegado)java.io.FileNotFoundException: C:\Test1 (Acceso denegado)
java.io.FileNotFoundException: C:\Test1 (Acceso denegado)
Translated would be something like "It was not possible copying the files. Motive: (Access denied)".
What I am trying to do is to copy a List into a directory recursively.
I could simply copy the files recursively (I already did that) but the requirements are to copy all into a List and then do whatever I want (copy, delete, etc) with the records in the list.
My List contains this records:
C:\Test\Carpeta_A
C:\Test\Carpeta_A\Entrenamiento_1.txt
C:\Test\Carpeta_A\Requerimientos.txt
C:\Test\Carpeta_B
C:\Test\Carpeta_B\queries.txt
C:\Test\Things.txt
Here is my code:
This is the main method.. it calls a method for listing and saving the files and directories and then calls the method for copying the files into another directory preserving my main structure:
public static void main(String[] args) throws IOException
{
String fuente = "C:/Test";
String ruta = "C:/Test1";
teeeeeest listing = new teeeeeest();
List<File> files = listing.getFileListing(fuente);
listing.copyDirectories(files, ruta);
}
public List<File> getFileListing( String fuente ) throws FileNotFoundException
{
List<File> result = getFileListingNoSort(fuente);
Collections.sort(result);
return result;
}
private List<File> getFileListingNoSort( String fuente ) throws FileNotFoundException
{
File source = new File(fuente);
List<File> result = new ArrayList<>();
File[] filesAndDirs = source.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for(File file : filesDirs) {
result.add(file); //always add, even if directory
String s = file.getPath().trim();
if (! file.isFile()) {
//must be a directory
//recursive call!
List<File> deeperList = getFileListingNoSort(s);
result.addAll(deeperList);
}
}
return result;
}
public static void copyDirectories(List<File> files, String destiny)
throws IOException
{
InputStream in = null;
OutputStream out = null;
File targetPath = new File(destiny);
System.out.println(targetPath.getPath());
for(int i = 0; i < files.size(); i++)
{
File temp = new File(files.get(i).toString());
//System.out.println(temp.getPath());
try
{
if(temp.isDirectory())
{
if(!targetPath.exists())
{
targetPath.mkdir();
}
File[] filesAndDirs = temp.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for(File file : filesDirs)
{
if (! file.isFile())
{
//must be a directory
//recursive call!
copyDirectories(filesDirs,destiny);
}
}
}
else
{
in = new FileInputStream(files.get(i).toString());
out = new FileOutputStream(targetPath);
System.out.println(temp.getPath());
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
{
out.write(buf, 0, len);
}
}
}
catch(Exception e)
{
System.err.println("No fue posible copiar los archivos. Motivo: " + e.getMessage() + e);
e.printStackTrace();
}
}
}
It would be very bad of me to just paste the working code here, it will not help you to think about what the problems are. I will try to give you enough without giving everything: Please mark my answer as accepted if it helps you.
1: You should not sort the file listing. The order the files are read in is important so that you don't get files before directories in your list. That said, it doesn't matter if you sort them because the shorter names, which are the directories, will appear first anyway. Still, don't do work you shouldn't be doing. Remove the getFileListing method and use only the getFileListingNoSort.
List<File> files = listing.getFileListingNoSort(fuente);
2: You need to pass both the source and the destination directories to copyDirectories so that you can make a destination filename from the source filename.
listing.copyDirectories(files, fuente, ruta);
3: You need to create a destination file out of the source filename. There may be better ways, but using simple String parsing will do the trick:
File temp = files.get(i);
String destFileName = destiny + temp.toString().substring(source.length());
File destFile = new File(destFileName);
4: You must create the new directories based on the new destFile. You are using the targetPath, which is only the base directory, not the new directory that needs to be created.
if(!destFile.exists())
{
destFile.mkdir();
}
5: After you make the destination directory, there is nothing else to do. Remove all that code after that up to the 'else'
6: Your outfile should be the new destFile you created.
out = new FileOutputStream(destFile);
7: close your input and output streams or the file copies will not be complete.
in.close();
out.close();
That should get you going. Use an IDE if you can so that you can step through the program with a debugger and see what's happening.
In your copyDirectories method calls the destiny is always the same value, even in recursive calls. You are copying all the files to the same destination file.

Java ZipEntry and Zipoutputstream directory

I have this little piece of code
public void doBuild() throws IOException {
ZipEntry sourceEntry=new ZipEntry(sourcePath);
ZipEntry assetEntry=new ZipEntry(assetPath);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("output/"+workOn.getName().replaceAll(".bld"," ")+buildNR+".zip"));
out.putNextEntry(sourceEntry);
out.putNextEntry(assetEntry);
out.close();
System.err.println("Build success!");
increaseBuild();
}
So, if I run it it runs trough it fine, creates the .zip and all, but the zip file is empty. sourceEntry and assetEntry are both directories. How could I get those directories to my .zip easily?
For those interested this is a MC mod build system and can be found at https://bitbucket.org/makerimages/makerbuild-system NOTE: the code above is not commited or pushed to there yet!!!!!!!!
Try something like this. The parameter useFullFileNames specifies
whether you want to preserve the full names of the paths to the
files which you're about to zip.
So if you have two files
/dir1/dir2/a.txt
and
/dir1/b.txt
the useFullFileNames specifies if you want to finally see in
the zip file those original paths to the two files or just
the two files with no paths like this
a.txt
and
b.txt
in the root of the zip file which you create.
Note that in my example, the files which are zipped
are actually read and then written to out.
I think you're missing that part.
public static boolean createZip(String fNameZip, boolean useFullFileNames, String... fNames) throws Exception {
try {
int cntBufferSize = 256 * 1024;
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(fNameZip);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte bBuffer[] = new byte[cntBufferSize];
File ftmp = null;
for (int i = 0; i < fNames.length; i++) {
if (fNames[i] != null) {
FileInputStream fi = new FileInputStream(fNames[i]);
origin = new BufferedInputStream(fi, cntBufferSize);
ftmp = new File(fNames[i]);
ZipEntry entry = new ZipEntry(useFullFileNames ? fNames[i] : ftmp.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(bBuffer, 0, cntBufferSize)) != -1) {
out.write(bBuffer, 0, count);
}
origin.close();
}
}
out.close();
return true;
} catch (Exception e) {
return false;
}
}

How to zip only .txt file in a folder using java?

here i'm trying to zip only .txt file in a folder using java.
My code here was found with google and works perfectly but only for a specified .txt file.
Thank you.
import java.util.*;
import java.util.zip.*;
import java.io.*;
public class ZipFile
{
public static void main(String[] args) {
ZipOutputStream out = null;
InputStream in = null;
try {
File inputFile1 = new File("c:\\Target\\target.txt");// here i want to say only the directroy where .txt files are stored
File outputFile = new File("c:\\Target\\Archive_target.zip");//here i want to put zipped file in a different directory
OutputStream rawOut = new BufferedOutputStream(new FileOutputStream(outputFile));
out = new ZipOutputStream(rawOut);
InputStream rawIn = new FileInputStream(inputFile1);
in = new BufferedInputStream(rawIn);
ZipEntry entry = new ZipEntry("c:\\Target\\target.txt");
out.putNextEntry(entry);
byte[] buf = new byte[2048];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
catch(IOException e) {
e.printStackTrace();
}
finally {
try {
if(in != null) {
in.close();
}
if(out != null) {
out.close();
}
}
catch(IOException ignored)
{ }
}
}
}
You need to use File.list(...) to get a list of all the text files in the folder. Then you create a loop to write each file to the zip file.
I just add these lines just after
"File outputFile = new File("c:\Target\Archive_target.zip");
from my previous code.
code added:
File Dir = new File("c:/Target");
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return !name.startsWith(".txt");
}
};
String[] children = Dir.list(filter);
You can get a list of all text files in your directory by using the following method of the File class:
String[] list(FilenameFilter filter)
Create a File object that points to your DIRECTORY (I know it sounds illogical, but that's the way it is- you can test if it is a directory using isDirectory()) and then use the FilenameFilter to say, for example, accept this file if its name contain ".txt"
Create a FilenameFilter that accepts only *.txt file , and then just use
list = File.list(yourNameFilter);
and then just add all the files in the list to the zip file

Categories