Copying a folder to a destination named the same thing - java

I'm trying to get a backup program to take a folder selected by the user using JFileChooser and copy it to a destination also selected using the same method.
The only problem is that it doesn't put all the contents of the selected folder into a folder in the destination named the same thing, and I really dont know why. I did some Googling, and I didnt find anything useful.
Here's the code:
package main;
import java.io.File;
import java.util.ArrayList;
public class test {
BackgroundWorker bw;
static ArrayList bgWorker = new ArrayList();
ArrayList al = new ArrayList(); // this is the list of files selected to
// back up
String dir = ""; // this is the path to back everything up to selected by
static // the user
boolean bwInitiallized = false;
public void startBackup() throws Exception {
Panel.txtArea.append("Starting Backup...\n");
for (int i = 0; i < al.size(); i++) {
/**
* THIS IS WHERE I NEED TO CREATE THE FOLDER THAT EACH BACKUP FILE
* WILL GO INTO EX: SC2 GOES INTO A FOLDER CALLED SC2 AND RIOT GOES
* TO RIOT, ALL WITHIN THE DIRECTORY CHOSEN
*/
File file = new File((String) al.get(i));
File directory = new File(dir);
// File dirFile = new File(dir + "\\" + file.getName());
// if (!dirFile.exists())
// dirFile.mkdir();
bw = new BackgroundWorker(Panel.txtArea, file, directory);
bgWorker.add(bw);
bwInitiallized = true;
bw.execute();
/**
* follows to the bottom of the txtarea
*/
int x;
Panel.txtArea.selectAll();
x = Panel.txtArea.getSelectionEnd();
Panel.txtArea.select(1, x);
}
clearList(); // method not included in this example that deletes all the
// contents of the al array list.
}
public static void cancel() {
BackgroundWorker bg;
if (bwInitiallized) {
bwInitiallized = false;
Panel.txtArea.append("Cancelling...\n");
for (int i = 0; i < bgWorker.size(); i++) {
// BackgroundWorker bg = (BackgroundWorker) bgWorker.get(i);
bg = (BackgroundWorker) bgWorker.get(i);
bg.cancel(true);
}
Panel.txtArea.append("Canceled backUp!\n");
} else {
Panel.txtArea.append("Cannot Cancel! Not Initiallized!\n");
}
}
}
What I think the problem is: I believe that for whatever reason the destination file path needs to have to the name of the folder included, but I tried that and it didnt help.
Does anyone know what I'm doing wrong?
This is the code that makes the JFileChooser:
public void fileChooserToDestination() {
LookAndFeel previousLF = UIManager.getLookAndFeel();
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
JFileChooser jfc = new JFileChooser();
try {
UIManager.setLookAndFeel(previousLF);
} catch (UnsupportedLookAndFeelException e) {
}
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (jfc.showDialog(null, "Select Directory") == JFileChooser.APPROVE_OPTION) {
File file = jfc.getSelectedFile();
dir = file.getPath();
Panel.txtArea.append("User selected " + file.getPath()
+ " for the destination...\n");
try {
startBackup();
} catch (Exception e) {
}
} else {
Dialogs.msg("You canceled selecting a destination folder! Returning to main screen...");
al.clear();
Panel.txtArea.append("User cancelled the destination selection..."
+ "\n");
}
return;
}

Parts of the code I need are missing. I can't see where you're making your decisions about how to append the source file to the destination path, so I wrote this quick example it illustrate the point...
File sourcePath = new File("/path/to/be/backed/up");
File destPath = new File("X:/BackupHere");
// Get all the files from sourcePath
List<File> listFiles = getFilesFrom(sourcePath);
for (File toBackup : listFiles) {
// Now we need to strip off the sourcePath
// Get the name of the file
String fileName = toBackup.getName();
// Get parent folder's path
String path = toBackup.getParent();
// Remove the source path from file path
path = path.substring(sourcePath.getPath().length());
// Append the file name to the path
path = path + File.separator + fileName;
// Now we have the name of the back up file
String backupFile = destPath + path;
System.out.println("Backup to " + backupFile);
}
Basically, you need to strip of the "source path" (the directory you want to copy). You then use the resulting value to append to the "backup path" value and you should then have a suitable path.

Related

How do I conditionally get code to loop back to specific point in code in java?

I am creating an application that automatically sorts and organizes files into a database​. I have written my code to read files within the imported folder one at a time, and process them into the DB. However, I am having trouble looping this process, so that I can process files that are nested in any amount of folders within the original folder that the user wants to input.
I simply need to instruct my program to go back to a specific part of my code and start running from there again.
Another possible way to solve this issue would be to create a way to list out all of the individual files within folder (including all the files within subfolders), and I could easily fit that into my program too.
I tried using labeled continue, return, and break keywords based off of an answer I got online, but I never expected those to succeed in looping my code back to a specific spot.
JFileChooser chooser = new JFileChooser();
chooser.setSelectedFiles(null);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.showOpenDialog(null);
//Getting file paths from within folder
File f = chooser.getSelectedFile();
String file = f.getAbsolutePath();
if (f.isDirectory()) {
//Need to loop back to here
File folder = new File(file);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isDirectory()) {
//Code here is run if there is a folder within a folder. I tested it too
//I want the code here to loop back above where it says "Need to loop back to here"
}
if (listOfFiles[i].isFile()) { //Once I list the files from within the folder, their information gets assigned variable here, and the rest of my program sorts it and saves it to DB accordingly.
//Everything below here is not important, but it might be helpful to see what happens each file with the folders.
System.out.println(listOfFiles[i]);
String filename = (listOfFiles[i].getName()); //For Files
Long filemodified = (listOfFiles[i].lastModified());
String filepath = (listOfFiles[i].getAbsolutePath());
Long filesizeraw = (listOfFiles[i].length());
long filehashcode = (listOfFiles[i].hashCode());
String fileparent = (listOfFiles[i].getParent());
Currently, there is no error message. It would process any individual files directly in the imported file (not nested in any folder within the folder), but wouldn't get to any of the files that are in folders within folders.
Another possible way to solve this issue would be to create a way to list out all of the individual files within folder (including all the files within subfolders), and I could easily fit that into my program too
Although this doesn't do the SQLite inserts, the following class extracts a list (of File objects) the files (thus file name and path are available via the File object).
public class FTS {
private ArrayList<File> mFileList; //Resultant list of Files extracted
private String mBaseDirectory; // The Directory to search
private long mSubDirectoryCount; // The count of the subdirectories
//Constructor
public FTS(String directory) {
this.mBaseDirectory = directory;
this.mSubDirectoryCount = 0;
buildFileListing(this.mBaseDirectory);
}
//
private void buildFileListing(String directory) {
// Initialise the ArrayList for the result
if (mFileList == null) {
mFileList = new ArrayList(){};
}
//Get the File (directory to process)
File dir = new File(directory);
// Get the List of the Directories contents
String[] filelist = dir.list();
// If empty (null) then return
if (filelist == null) {
return;
}
// Loop through the directory list
for (String s: filelist) {
//get the current list item as a file
File f = new File(dir.getAbsolutePath() + File.separator + s);
// is it a file or directory?
if (f.isFile() && !f.isDirectory()) {
this.mFileList.add(f); // If a file then add the file to the extracted list
} else {
// If a directory then increment the count of the subdirectories processed
mSubDirectoryCount++;
// and then recursively call this method to process the directory
buildFileListing(f.getAbsolutePath());
}
}
}
// return the list of extracted files
public ArrayList<File> getFileList() {
return this.mFileList;
}
// return the number of sub-directories processed
public long getSubDirectoryCount() {
return this.mSubDirectoryCount;
}
}
An example usage of the above is :-
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
FTS fileTreeSearch;
String BaseDirectory = "E:" + File.separator;
List<File> files = (fileTreeSearch = new FTS(BaseDirectory)).getFileList();
System.out.println("Extracted " + String.valueOf(files.size()) + " files, from " + String.valueOf(fileTreeSearch.getSubDirectoryCount()) + " sub-directories of " + BaseDirectory);
/* this commented out code would process all the extracted files
for (File f: files) {
System.out.println("File is " + f.getName() + "\t\t path " + f.getAbsolutePath());
}
*/
}
}
Example output from running the above :-
Extracted 186893 files, from 54006 sub-directories of E:\

Error in Renaming Files

Although there are many questions here that involve errors with naming files, the code below tries to implement those examples but fails to actually change the name of the file in the system for no apparent reason.
public static void main(String[] args)
{
File dir = new File("E:/Vglut2 pharmacology/60730/");
File[] directoryListing = dir.listFiles();
for (File filius : directoryListing) {
try
{
String oldName = filius.getName();
int imgNum = returnImageNumber(oldName);
double imgMag = returnImageMagnification(oldName);
String newName = oldName.substring(0, oldName.indexOf('_')).concat('_' + String.valueOf(imgNum)).concat('_' + String.valueOf(imgMag));
File nova = new File(newName);
filius.renameTo(nova);
System.out.println(newName);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
The resulting string that I tested by printing offers the desired resulting final name, however, in the end, the filesystem remains unchanged. A similar example from a previous stack overflow question is as seen below-
File dir = new File("D:/xyz");
if (dir.isDirectory()) { // make sure it's a directory
for (final File f : dir.listFiles()) {
try {
File newfile =new File("newfile.txt");
if(f.renameTo(newfile)){
System.out.println("Rename succesful");
}else{
System.out.println("Rename failed");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
As seen there are no significant differences that I can tell which would affect the viability of this process. Note I am running Windows 10 Home edition as an admin if this is related. Thanks for the help.
filius.getName() only gets the last part of the files path. renameTo on the other hand needs the full path. So in fact you end up trying to move your file into a different directory.
Use:
File nova = new File(dir, newName);
in order to rename the file in the original directory.

Can't make Files and Folders

So i'm working on a simple Windows Explorer replacement. I want to add the ability to create Folders and Files. For some reason, it only works when i'm in my root or c:/ folder, but as soon as it's somewhere else (for example C:\Program Files (x86)) it doesn't work. I either get a java.io.IOException: Access Denied when i create a File and when i try to create a folder, no Exception comes up, but no folder is created.
This is my code for a new file:
String location = getPath();
String name = JOptionPane.showInputDialog("Fill in the name of the new file. \nDon't forget to add file type (.txt, .pdf).", null);
if(name == null){
}
else {
File newFile = new File(location + "\\" + name);
boolean flag = false;
try {
flag = newFile.createNewFile();
} catch (IOException Io) {
JFrame messageDialog = new JFrame("Error!");
JOptionPane.showMessageDialog(messageDialog, "File creation failed with the following reason: \n" + Io);
}
}
This is my code for a new Folder:
String location = getPath();
String name = JOptionPane.showInputDialog("Fill in the name of the new folder.", null);
if(name == null){
}
else {
File newFolder = new File(location + "\\" + name);
boolean flag = false;
try {
flag = newFolder.mkdir();
} catch (SecurityException Se) {
JFrame messageDialog = new JFrame("Error!");
JOptionPane.showMessageDialog(messageDialog, "Folder creation failed with the following reason: \n" + Se);
}
}
I'm stuck right now and i have no idea what i'm doing wrong to get rid of the access denied error.
Short explenation of how this program works:
My program shows a list of all folders and files from a selected File.
That File is a field in the class JXploreFile called "currentFile", which behaves almost the same as a File.
When browsing through the folders, the currentFile is set to a new JXploreFile, containing the new folder you are in as File.
When creating a new folder/file, my program ask the path the user is currently browsing in with the method getPath().
Thanks for the help!
Image of my program:
Before you try to make any I/O operation just check if you have the permission
go to the parent directory (your case location)
then do something like
File f = new File(location);
if(f.canWrite()) {
/*your full folder creation code here */
} else {
}
try to put
String location ="c:\\user\<<youruser>>\\my documents"
or a folder with full perission to write

Setting the root context of the created jar file when using JarOutputStream

I'm writing a short application that opens a .jar file, runs a few transforms on its contents, then wraps it up as a .jar file again. I'm using the approach from How to use JarOutputStream to create a JAR file? to create the new jar file and it's working with the exception that it's creating a file hierarchy in new jar file that stretches all the way back to my computer's root.
It's perfectly logical that this is happening since I'm passing the process the target directory as a path from the computer root. What I can't find is any other way of communicating the context that process needs to be able to find my target folder. How do I set the context from which I want the .jar file to be created?
To clarify:
I've rewritten the Run method of the solution linked above to accept two parameters: a string defining the name and location of the output jar file and a string defining the location of the folder I want compressed, like so:
public void run(String output, String inputDirectory) throws IOException
{
JarOutputStream target = new JarOutputStream(new FileOutputStream(output));
add(new File(inputDirectory), target, inputDirectory.length());
target.close();
}
Two sample values that I hand off to the method would be: C:/temp/964ca469-5f7b-4c56-8b5a-72b4c1c851e0/help.jar and C:/temp/964ca469-5f7b-4c56-8b5a-72b4c1c851e0/out/
I want the structure of my .jar file to have its root at the forward slash following "out", but instead the .jar file's hierarchy is:
C:
|-Temp
|-964ca469-5f7b-4c56-8b5a-72b4c1c851e0
|-out
|-{content}
I've tried passing the length of the string preceding the actual content to the Add method and paring it off before adding the JarEntry, but that just gets me an out of index error, which makes perfect sense because I'm just frikkin' groping.
There must be a way of setting the JarEntry class to a specific point in a folder hierarchy before adding a file, or some other means of doing the same thing, but I canna find it so far.
Thanks.
There is no 'root context' in a JAR file. What the files and paths are is completely dependent on what name(s) you put into the JarEntries.
Never figured out how to do it with Jar file creation, but as fge suggested the zip filesystem provider was indeed easier to work with. I used this in my main method:
CreateJarPackage zipper = new CreateJarPackage();
System.out.println(baseline + unique_directory + "/" + out_jar_file);
System.out.println(baseline + unique_directory + "/out/");
System.out.println(baseline.length() + unique_directory.length() + 5);
try {
zipper.addZipFiles(baseline + unique_directory + "/" + out_jar_file, baseline + unique_directory + "/out/", baseline.length() + unique_directory.length() + 5);
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File folder = new File(baseline + unique_directory + "/out/");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isDirectory()) {
try {
zipper.addZipFiles(baseline + unique_directory + "/" + out_jar_file, listOfFiles[i].toString(), baseline.length() + unique_directory.length() + 5);
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
To call this:
import java.io.File;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
public class FinalZipCreator {
public static void processList(URI uri, Map<String, String> env, String path)
throws Throwable {
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
int index = path.length();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
Path externalTxtFile =Paths.get(listOfFiles[i].toString());
Path pathInZipfile = zipfs.getPath(listOfFiles[i]
.toString().substring(index));
// copy a file into the zip file
Files.copy(externalTxtFile, pathInZipfile,
StandardCopyOption.REPLACE_EXISTING);
} else if (listOfFiles[i].isDirectory()) {
Path externalTxtFile = Paths.get(listOfFiles[i].toString());
Path pathInZipfile = zipfs.getPath(listOfFiles[i]
.toString().substring(index));
// copy a file into the zip file
Files.copy(externalTxtFile, pathInZipfile,
StandardCopyOption.REPLACE_EXISTING);
File folder2 = new File(listOfFiles[i].toString());
File[] listOfFiles2 = folder2.listFiles();
int index2 = listOfFiles[i].toString().length();
for (int e = 0; e < listOfFiles2.length; e++) {
if (listOfFiles2[i].isFile()) {
Path externalTxtFile2 = Paths.get(listOfFiles2[e].toString());
Path pathInZipfile2 = zipfs.getPath(listOfFiles2[e]
.toString().substring(index2));
// copy a file into the zip file
Files.copy(externalTxtFile2, pathInZipfile2,
StandardCopyOption.REPLACE_EXISTING);
}
}
}
}}
}
}
There's likely a zillion better ways of doing it, but it worked. Thanks for the help.
As a side note, it's the equivalent of the "pathInZipFile" function that I could never locate in the Jar creator.

Java Directory Listing problem

I want to list all the folders of the current directory but there are two problems. Everytime i run this program, the list shows all the files of the last folder inside the directory and the filter does not work.
Can you please help me?
public void foldersPanel()
{
JPanel folderScreen = new JPanel();
folderScreen.setLayout(new GridLayout(1,1));
direFilter = new FilenameFilter()
{
public boolean accept(File file, String string)
{
if (file.isDirectory())
{
return file.isDirectory();
}
else
{
return false;
}
}
};
File directory = new File(System.getProperty("user.dir"));
File[] listOfFiles = directory.listFiles(direFilter);
String[] allFiles = directory.list();
if (directory.isDirectory())
{
int x = 1;
for (int i =0; i<listOfFiles.length; i++) // displays all the files
{
if (listOfFiles[i].isDirectory())
{
folderList = new JList(listOfFiles[i].list(direFilter));
System.out.println(x +") Directory = " + listOfFiles[i].getName());
x++;
folderList.setSelectedIndex(1);
}
else
{
System.out.println("is file");
}
folderScreen.add(new JScrollPane(folderList));
}
}
else
{
System.out.println("This is a file, not a directory, so we will move to the parent folder");
directory = directory.getParentFile();
updateLabels();
System.out.println("The new directory is : " +directory.toString());
}
}
code
Your method isn't recursive. A directory is a tree; you want to recursively call a method that adds the list of files to an overall list if it's a directory, or simply add the file if it's a file. Keep accumulating all the lists and you'll have every file under the root directory.
The first parameter of FilenameFilter.accept is the containing directory. Effectively, your test will always return true.
[EDIT]
More specifically, I think you really want your test to be:
public boolean accept(File dir, String fileName) {
return new File(dir, fileName).isDirectory();
}

Categories

Resources