Copy multiple files in java - java

i tried
private boolean CopyFiles(List<File> selected)
{
try {
File mNewFile = new File("/home/ubuntu/Desktop");
mNewFile.createNewFile();
FileUtils.copyFile(selected,mNewFile);
return true;
} catch (IOException ex) {
Logger.getLogger(CommonMethod.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
in above code for copy file FileUtild.copyFile(File src, File dest) method dose not support for multiple file copy any idea for that?

I assume that you are using org.apache.commons.io.FileUtils and that "/home/ubuntu/Desktop" is a directory.
In this case you can do it like this:
nNewFile.mkdirs();
for(File f : selected) {
FileUtils.copyFileToDirectory(f, nNewFile);
}

you can use org.apache.commons.io.FileUtils to copy files from one location to another
private void copyFiles(List<File> selected, File destinationDirectory)
{
for(File file : selected){
try {
if (!destinationDirectory.exists())
destinationDirectory.mkdir();
FileUtils.copyFileToDirectory(file,destinationDirectory);
} catch (IOException ex) {
Logger.getLogger(CommonMethod.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Related

Moving a directory in java throws java.nio.file.FileAlreadyExistsException

I am creating a rollback feature and here is what I have and wanna achieve:
a tmp folder is created in the same location as the data folder;
before doing any operation I copy all the contents from data folder to tmp folder (small amount of data).
On rollback I want to delete the data folder and rename tmp folder to data folder.
This is what I tried
String contentPath = "c:\\temp\\data";
String tmpContentPath = "c:\\temp\\data.TMP";
if (Files.exists(Paths.get(tmpContentPath)) && Files.list(Paths.get(tmpContentPath)).count() > 0) {
FileUtils.deleteDirectory(new File(contentPath));
Files.move(Paths.get(tmpContentPath), Paths.get(contentPath), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
}
but this throws FileAlreadyExistsException even though I deleted the target directory in the same method.
Once the program exits I don't see the c:\temp\data directory, so the directory is actually deleted.
Now if I try StandardCopyOption.ATOMIC_MOVE it throws an java.nio.file.AccessDeniedException.
What is the best way to move tmp dir to data dir in these kind of situations?
Actually in java 7 or above you can just use the Files to achieve the folder moving even there is a conflict, which means the target folder already exists.
private static void moveFolder(Path thePath, Path targetPath) {
if (Files.exists(targetPath)) { // if the target folder exists, delete it first;
deleteFolder(targetPath);
}
try {
Files.move(thePath, targetPath);
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void deleteFolder(Path path) {
try {
if (Files.isRegularFile(path)) { // delete regular file directly;
Files.delete(path);
return;
}
try (Stream<Path> paths = Files.walk(path)) {
paths.filter(p -> p.compareTo(path) != 0).forEach(p -> deleteFolder(p)); // delete all the children folders or files;
Files.delete(path); // delete the folder itself;
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
Try This
public class MoveFolder
{
public static void main(String[] args) throws IOException
{
File sourceFolder = new File("c:\\temp\\data.TMP");
File destinationFolder = new File("c:\\temp\\data");
if (destinationFolder.exists())
{
destinationFolder.delete();
}
copyAllData(sourceFolder, destinationFolder);
}
private static void copyAllData(File sourceFolder, File destinationFolder)
throws IOException
{
destinationFolder.mkdir();
String files[] = sourceFolder.list();
for (String file : files)
{
File srcFile = new File(sourceFolder, file);
File destFile = new File(destinationFolder, file);
copyAllData(srcFile, destFile); //call recursive
}
}
}
Figured out the issue. In my code before doing a rollback, I am doing a backup, in that method I am using this section to do the copy
if (Files.exists(Paths.get(contentPath)) && Files.list(Paths.get(contentPath)).count() > 0) {
copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));
}
Changed it to
try (Stream<Path> fileList = Files.list(Paths.get(contentPath))) {
if (Files.exists(Paths.get(contentPath)) && fileList.count() > 0) {
copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));
}
}
to fix the issue

How do I force mkdir to overwrite existing directory?

I need to have my program create a directory with a specific name, and overwrite any existing directory with that name. Currently, my program doesn't seem to be able to overwrite the directory. Is there any way of forcing the overwrite?
private boolean makeDirectory(){
File file = new File(TEMP_DIR_PATH + "/" + clipName);
if (file.mkdir()) {
return true;
}
else {
System.err.println("Failed to create directory!");
return false;
}
}
EDIT:
Now I'm trying the following, but the program is not detecting that the directory exists, even though it does.
private boolean makeDirectory(String path){
File file = new File(path);
if (file.exists()) {
System.out.println("exists");
if (file.delete()) {
System.out.println("deleted");
}
}
if (file.mkdir()) {
return true;
}
else {
System.err.println("Failed to create directory!");
return false;
}
}
RESOLVED:
(If anyone else in the future needs to know...)
I ended up doing it this way:
private boolean makeDirectory(String path){
if (Files.exists(Paths.get(path))) {
try {
FileUtils.deleteDirectory(new File(path));
}
catch (IOException ex) {
System.err.println("Failed to create directory!");
return false;
}
}
if (new File(path).mkdir()) {
return true;
}
return false;
}
You want to delete the directory first if it exists, then recreate it.
Using java.nio.file.Files
if (Files.exists(path)) {
new File("/dir/path").delete();
}
new File("/dir/path").mkdir();
and if you have FileUtils, this might be preferable as it avoids actually deleting a directory you want to be there:
import org.apache.commons.io.FileUtils
if (Files.exists(path)) {
FileUtils.cleanDirectory( new File("/dir/path"));
} else {
new File("/dir/path").mkdir();
}
You can import this library import org.apache.commons.io.FileUtils; and then you could write your code like this:
private boolean makeDirectory(){
File file = new File(TEMP_DIR_PATH + "/" + clipName);
boolean returnValue = false;
try {
FileUtils.forceMkdir(file);
returnValue = true;
} catch (IOException e) {
throw new RuntimeException(e);
}
return returnValue;
}
Check if the directory exists,
If so, delete that directory
Create directory

FileNotFoundException with FileOutputStream open

I'm having a FileNotFoundException when i try to create a FileOutputStream. The file does exists according to file.exists. i've tried everything like file.mkdir(s) ...
I'm on a mac and i'm using gauva.
The file input is ''
java.io.FileNotFoundException: /Users/big_Xplosion/mods/Blaze-Installer/installer/test
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
at com.google.common.io.Files$FileByteSink.openStream(Files.java:223)
at com.google.common.io.Files$FileByteSink.openStream(Files.java:211)
at com.google.common.io.ByteSource.copyTo(ByteSource.java:203)
at com.google.common.io.Files.copy(Files.java:382)
at com.big_Xplosion.blazeInstaller.util.DownloadUtil.downloadFile(DownloadUtil.java:80)
at com.big_Xplosion.blazeInstaller.action.MCPInstall.downloadMCP(MCPInstall.java:78)
at com.big_Xplosion.blazeInstaller.action.MCPInstall.install(MCPInstall.java:30)
at com.big_Xplosion.blazeInstaller.util.InstallType.install(InstallType.java:37)
at com.big_Xplosion.blazeInstaller.BlazeInstaller.handleOptions(BlazeInstaller.java:51)
at com.big_Xplosion.blazeInstaller.BlazeInstaller.main(BlazeInstaller.java:26)
the code in the main class.
File file = mcpSpec.value(options); //the file input given is 'test'
try
{
InstallType.MCP.install(file.getAbsoluteFile());
}
catch (IOException e)
{
e.printStackTrace();
}
The execution code The mcpTarget file has to be a directory
public boolean install(File mcpTarget) throws IOException
{
mcpTarget.mkdirs();
if (isMCPInstalled(mcpTarget))
System.out.println(String.format("MCP is already installed in %s, skipped download and extraction.", mcpTarget));
else if (isMCPDownloaded(mcpTarget))
{
if (!unpackMCPZip(mcpTarget))
return false;
}
else
{
if (!downloadMCP(mcpTarget))
return false;
if (!unpackMCPZip(mcpTarget))
return false;
}
System.out.println("Successfully downloaded and unpacked MCP");
return false;
}
Download MCP method
public boolean downloadMCP(File targetFile)
{
String mcpURL = new UnresolvedString(LibURL.MCP_DOWNLOAD_URL, new VersionResolver()).call();
if (!DownloadUtil.downloadFile("MCP", targetFile, mcpURL))
{
System.out.println("Failed to download MCP, please try again and if it still doesn't work contact a dev.");
return false;
}
return true;
}
and the DownloadUtil.DownloadFile method
public static boolean downloadFile(String name, File path, String downloadUrl)
{
System.out.println(String.format("Attempt at downloading file: %s", name));
try
{
URL url = new URL(downloadUrl);
final URLConnection connection = url.openConnection();
connection.setConnectTimeout(6000);
connection.setReadTimeout(6000);
InputSupplier<InputStream> urlSupplier = new InputSupplier<InputStream>()
{
#Override
public InputStream getInput() throws IOException
{
return connection.getInputStream();
}
};
Files.copy(urlSupplier, path);
return true;
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
mcpTarget.mkdirs();
mcpTarget.mkdir();
This is the problem. You are creating a folder at the specified file. Replace this with
mcpTarget.getParentFile().mkdirs();
(or, since you use Guava, use this: Files.createParentDirs(mcpTarget))
Also, the latter is a subset of the former, so you never need to call both of the mkdir methods.

How to find sub-directories in a directory/folder?

I'm looking for a way to get all the names of directories in a given directory, but not files.
For example, let's say I have a folder called Parent, and inside that I have 3 folders: Child1 Child2 and Child3.
I want to get the names of the folders, but don't care about the contents, or the names of subfolders inside Child1, Child2, etc.
Is there a simple way to do this?
If you are on java 7, you might wanna try using the support provided in
package java.nio.file
If your directory has many entries, it will be able to start listing them without reading them all into memory first. read more in the javadoc: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#newDirectoryStream(java.nio.file.Path,%20java.lang.String)
Here is also that example adapted to your needs:
public static void main(String[] args) {
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
#Override
public boolean accept(Path file) throws IOException {
return (Files.isDirectory(file));
}
};
Path dir = FileSystems.getDefault().getPath("c:/");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
for (Path path : stream) {
// Iterate over the paths in the directory and print filenames
System.out.println(path.getFileName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
You can use String[] directories = file.list() to list all file names,
then use loop to check each sub-files and use file.isDirectory() function to get subdirectories.
For example:
File file = new File("C:\\Windows");
String[] names = file.list();
for(String name : names)
{
if (new File("C:\\Windows\\" + name).isDirectory())
{
System.out.println(name);
}
}
public static void displayDirectoryContents(File dir) {
try {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
System.out.println("Directory Name==>:" + file.getCanonicalPath());
displayDirectoryContents(file);
} else {
System.out.println("file Not Acess===>" + file.getCanonicalPath());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
====inside class/Method provide File=URL ======
File currentDir = new File("/home/akshya/NetBeansProjects/");
displayDirectoryContents(currentDir);
}

A properties file I created in the 1st run gets blanked in the 2nd run

Okay, I'm trying to create a custom client for Minecraft (don't worry, my question has nothing to do with Minecraft in particular), and I added an abstract class to manage a configuration file using Java's built-in Properties system. I have a method that loads a properties file or creates it if it doesn't already exist. This method is called at the beginning of all my other methods (although it only does anything the first time its called).
The properties file gets created just fine when I run Minecraft the first time, but somehow when I run it the second time, the file gets blanked out. I'm not sure where or why or how I'm wiping the file clean, can someone please help me? Here's my code; the offending method is loadConfig():
package net.minecraft.src;
import java.util.*;
import java.util.regex.*;
import java.io.*;
/**
* Class for managing my custom client's properties
*
* #author oxguy3
*/
public abstract class OxProps
{
public static boolean configloaded = false;
private static Properties props = new Properties();
private static String[] usernames;
public static void loadConfig() {
System.out.println("loadConfig() called");
if (!configloaded) {
System.out.println("loading config for the first time");
File cfile = new File("oxconfig.properties");
boolean configisnew;
if (!cfile.exists()) {
System.out.println("cfile failed exists(), creating blank file");
try {
configisnew = cfile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
configisnew=true;
}
} else {
System.out.println("cfile passed exists(), proceding");
configisnew=false;
}
FileInputStream cin = null;
FileOutputStream cout = null;
try {
cin = new FileInputStream(cfile);
cout = new FileOutputStream(cfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (!configisnew) { //if the config already existed
System.out.println("config already existed");
try {
props.load(cin);
} catch (IOException e) {
e.printStackTrace();
}
} else { //if it doesn't exist, and therefore needs to be created
System.out.println("creating new config");
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
try {
props.store(cout, "OXGUY3'S CUSTOM CLIENT\n\ncloak_url is the URL to get custom cloaks from\nnames are the usernames to give cloaks to\n");
cout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
String names = props.getProperty("names");
System.out.println("names: "+names);
try {
usernames = Pattern.compile(", ").split(names);
} catch (NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("usernames: "+Arrays.toString(usernames));
configloaded=true;
}
}
public static boolean checkUsername(String username) {
loadConfig();
System.out.println("Checking username...");
for (int i=0; i<usernames.length; i++) {
System.out.println("comparing "+username+" with config value "+usernames[i]);
if (username.startsWith(usernames[i])){
System.out.println("we got a match!");
return true;
}
}
System.out.println("no match found");
return false;
}
public static String getCloakUrl() {
loadConfig();
return props.getProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
}
}
If it's too hard to read here, it's also on Pastebin: http://pastebin.com/9UscXWap
Thanks!
You are unconditionally creating new FileOutputStream(cfile). This will overwrite the existing file with an empty one. You should only invoke the FileOutputStream constructor when writing a new config file.
if (configloaded)
return;
File cfile = new File("oxconfig.properties");
try {
if (cfile.createNewFile()) {
try {
FileOutputStream cout = new FileOutputStream(cfile);
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://...");
...
cout.flush();
} finally {
cout.close();
}
} else {
FileInputStream cin = new FileInputStream(cfile);
try {
props.load(cin);
} finally {
cin.close();
}
}
configloaded=true;
} catch(IOException ex) {
e.printStackTrace();
}

Categories