I was listing the files in one folder and then I have to transfer them to another. However, the problem I get is the following ... When trying to paste them to the other folder the path is like E: \ Files, which causes me to generate some kind of file and it does not stick to me like it should . I tried several ways and still can not do it, I leave my code to see if you can help me
Path algo = Paths.get("E:/Files/");
public void Copy(String origenArchivo, Path algo) {
Path origenPath = Paths.get(origenArchivo);
String s = algo.toAbsolutePath().toString();
System.out.println(s);
Path destinoPath = Paths.get(s);
System.out.println(destinoPath);
String x = destinoPath.toString() + "/";
Path conv = Paths.get(x);
System.out.println(conv);
try {
Files.copy(origenPath, conv, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getLogger(Metodos.class.getName()).log(Level.SEVERE, null, ex);
}
}
File dir = new File("C:/Users/PC/Desktop/");
public void TravelToFantasy(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
Copy(listFile[i]);
} else {
System.out.println(listFile[i].getPath());
System.out.println(destino);
this.Copy(listFile[i].getPath(), algo);
}
}
}
}
I was trying to put the "/" to the path Paths.get gets me, but it always ends up leaving me the path as E:\Files
Thanks four you!
You cannot pass a directory to Files.copy.
You don’t need all that conversion to and from strings. Just use Path.resolve instead:
public void copy(String origenArchivo, Path algo)
throws IOException {
Path origenPath = Paths.get(origenArchivo);
Path conv = algo.resolve(origenPath.getFileName());
Files.copy(origenPath, conv, StandardCopyOption.REPLACE_EXISTING);
}
As a side note, the Path/Paths/Files classes are superior to the java.io.File class, because they provide meaningful information if an operation fails. You should not use java.io.File at all:
Path dir = Paths.get("C:/Users/PC/Desktop/");
public void TravelToFantasy(Path dir)
throws IOException {
try (DirectoryStream<Path> listFile = Files.newDirectoryStream(dir)) {
for (Path file : listFile) {
if (Files.isDirectory(file)) {
Copy(file);
} else {
System.out.println(file);
System.out.println(destino);
this.Copy(file, algo);
}
}
}
}
Use java.io.File.separator instead of "/", this will help your code to run any OS.
Related
I have a project structure like below:
Now, my problem statement is I have to iterate resources folder, and given a key, I have to find that specific folder and its files.
For that, I have written a below code with the recursive approach but I am not getting the output as intended:
public class ConfigFileReader {
public static void main(String[] args) throws Exception {
System.out.println("Print L");
String path = "C:\\...\\ConfigFileReader\\src\\resources\\";
//FileReader reader = new FileReader(path + "\\Encounter\\Encounter.properties");
//Properties p = new Properties();
//p.load(reader);
File[] files = new File(path).listFiles();
String resourceType = "Encounter";
System.out.println(navigateDirectoriesAndFindTheFile(resourceType, files));
}
public static String navigateDirectoriesAndFindTheFile(String inputResourceString, File[] files) {
String entirePathOfTheIntendedFile = "";
for (File file : files) {
if (file.isDirectory()) {
navigateDirectoriesAndFindTheFile(inputResourceString, file.listFiles());
System.out.println("Directory: " + file.getName());
if (file.getName().startsWith(inputResourceString)) {
entirePathOfTheIntendedFile = file.getPath();
}
} else {
System.out.print("Inside...");
entirePathOfTheIntendedFile = file.getPath();
}
}
return entirePathOfTheIntendedFile;
}
}
Output:
The output should return C:\....\Encounter\Encounter.properties as the path.
First of all, if it finds the string while traversing it should return the file inside that folder and without navigating the further part as well as what is the best way to iterate over suppose 1k files because every time I can't follow this method because it doesn't seem an effective way of doing it. So, how can I use an in-memory approach for this problem? Please guide me through it.
You will need to check the output of recursive call and pass that back when a match is found.
Always use File or Path to handle filenames.
Assuming that I've understood the logic of the search, try this which scans for files of form XXX\XXXyyyy
public class ConfigReader
{
public static void main(String[] args) throws Exception {
System.out.println("Print L");
File path = new File(args[0]).getAbsoluteFile();
String resourceType = "Encounter";
System.out.println(navigateDirectoriesAndFindTheFile(resourceType, path));
}
public static File navigateDirectoriesAndFindTheFile(String inputResourceString, File path) {
File[] files = path.listFiles();
File found = null;
for (int i = 0; found == null && files != null && i < files.length; i++) {
File file = files[i];
if (file.isDirectory()) {
found = navigateDirectoriesAndFindTheFile(inputResourceString, file);
} else if (file.getName().startsWith(inputResourceString) && file.getParentFile().getName().equals(inputResourceString)) {
found = file;
}
}
return found;
}
}
If this is slow especially for 1K of files re-write with Files.walkFileTree which would be much faster than File.list() in recursion.
I've got a widget that allows the user to drag and drop an email message or a file into the widget to copy it to their file system. It's the FileExplorer project in OpenNTF, designed by people far more experienced than I am. I want to modify it to provide a new filename if the current filename already exists in the location they're dropping it on. With emails I'd hoped to be able to grab the sender and date, but I've been throwing errors when I try to access the file contents during a drag-and-drop of email.
So, my issue is actually simple. I've got the 'if' to determine if the filename is taken, but I'm overwhelmed trying to figure out how to test multiple options for the filename (like numbering then 'file1.eml', 'file2.eml', 'file3.eml'). I tried, below, inserting the word DUPLICATE, but I'm having no joy.
try {
if (source.isDirectory()) {
File dirTarget = new File(fDest.getAbsoluteFile() + File.separator + source.getName());
if (!dirTarget.exists()) {
dirTarget.mkdir();
}
copyDir(monitor, source, dirTarget);
}
if (source.isFile()) {
File dest = new File(fDest.getAbsolutePath() + File.separator + source.getName());
if (dest.getAbsolutePath().compareTo(source.getAbsolutePath()) != 0) {
copyFile(monitor, source, dest);
} else {
dest = new File(fDest.getAbsolutePath() + File.separator + "DUPLICATE" + File.separator + source.getName());
copyFile(monitor, source, dest);
}
}
} catch (IOException e) {
}
For reference, the copyFile method's parameters are
private void copyFile(IProgressMonitor monitor, File fSource, File fTarget) throws IOException
You need to construct your file name different.
File.seperator
results in / \ or : depending on your platform since it is the char separating the directory from the file.
Since you are dropping a file, you don't need check for the directory, up to you. You need a loop to test file names. To make it easy use (DUPLICATE 1) (DUPLICATE 2) etc. Something like this:
private final static String DUPLICATE = "DUPLICATE";
private void copyOut(File source, File fDest, Monitor monitor) {
try {
if (!source.exists() || !fDest.exists()) {
// one or two files missing, can't copy
// handle error here!
} else {
String destName = fDest.getAbsolutePath()+ File.separator + source.getName();
File dest = new File(destName);
if (source.isDirectory()) {
if (!dest.exists()) {
destPath.mkdirs(); // Fix missing
} else if (dest.isFile()) {
// Raise an error. Destination exists as file source is directory!!!
}
} else { // We checked for existence and dir, so it is a file
// Don't overwrite an existing file
dest = this.checkforDuplicate(dest);
}
copyFile(monitor, source, dest);
}
} catch (IOException e) {
// Error handling missing here!
}
}
private File checkforDuplicate(File dest) {
if (!dest.exists()) {
return dest;
}
int duplicateNum = 1;
while (true) {
ArrayList<String> pieces = Arrays.asList(dest.getAbsolutePath().split("."));
pieces.add(pieces.size()-1, DUPLICATE);
if (duplicateNum > 1) {
pieces.add(pieces.size()-1,Integer.toString(duplicateNum));
}
duplicateNum++;
StringBuilder newName = newStringBuilder();
for (String s : pieces) {
newName.append(s);
newName.append(".");
}
// Strip the last .
String outName = newName.substring(0, newName.length()-2);
File result = new File(outName);
if (!result.exists()) {
return result;
}
}
}
Check the code, written off memory, will contain typos. also doesn't deal with file names that don't contain a dot.
I currently have a big folder full of filenames in the format:
EXA_0100_01012014.csv
EXA_0114_11012014.csv
Always the same 3 letters at the start. I need to change all of these filenames so that they are in the format:
EXA_B_0100_01012014
So it's just a case of inserting an _B (always _B) after the first three letters. I'm only just started learning Java so my attempts so far are fairly limited:
File oldfile = new File("EXA_0100_01012014.csv");
File newfile = new File("EXA_B_0100_01012014.csv");
I just need to do this for a large number of files all with the same 3 letter prefix. All the numbers change from file to file though.
If someone could give me a nudge in the right direction it would be much appreciated.
Thanks.
Use substring.
String fileName = "EXA_0100_01012014";
String newFileName = fileName.substring(0, 3) + "_B_" + fileName.substring(4);
Returns newFileName as:
EXA_B_0100_01012014
My suggestion:
String newFilename = oldfile.getFileName().replace("EXA_", "EXA_B_");
oldfile.renameTo(new File(newFilename));
If you don't like the replace() approach you could use the substring() method instead.
String oldFilename = oldfile.getFileName();
String newFilename = oldFilename.substring(0, 3) + "_B_" + oldFilename.substring(4);
oldfile.renameTo(new File(newFilename));
Here is the results from a quick google bomb:
First start looking at the renaming a file, Then you can instert a string by breaking the substrings apart and the prepending the first 3 characters and appending the rest after "_B". Similar to this.
public static void main(String[] h) {
final File folder = new File("/home/you/Desktop");
renameFilesForFolder(folder);
}
public static void renameFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
renameFilesForFolder(fileEntry);
} else {
if (fileEntry.getName().startsWith("EXA")) {
fileEntry.renameTo(new File(fileEntry.getName().replaceAll("(EXA)(_)", "$1_B$2")));
}
}
}
}
Here is a possible solution.
I used the following links to help me:
Nagesh Chauhan's solution for file renaming
http://www.beingjavaguys.com/2013/08/create-delete-rename-file-in-java.html
Philip Reichart's solution on file list
How to get contents of a folder and put into an ArrayList
import java.io.File;
import java.io.IOException;
public class RenameFiles
{
public RenameFiles()
{
File f = new File ("C:/work/play/java/list");
File[] list = f.listFiles();
for (int inum = 0; inum < list.length; inum++)
{
File curf = list[inum];
RenameFile(curf);
}
}
public void RenameFile(File curf)
{
String strfilename = curf.getAbsolutePath();
StringBuffer buf = new StringBuffer(strfilename);
int index = buf.indexOf("EXA_");
buf.insert(index+4, "B_");
String strnewfilename = buf.toString();
strnewfilename = strnewfilename.replace('\\', '/');
System.out.println(strnewfilename);
File newFileName = new File(strnewfilename);
try {
if (curf.renameTo(newFileName)) {
System.out.println("File "+strfilename+"renamed to "+strnewfilename+" successful !");
} else {
System.out.println("File "+strfilename+"renamed to "+strnewfilename+" failed !");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)
{
RenameFiles fobj = new RenameFiles();
}
}
I want to add a series of files previously extracted from other files(already done) to a jar. These files will be overwriting files inside the JAR. What is the most efficient way to do it?
I need it to be fast.
Thank you!
jar -uf my.jar file1 file2...
jar -uf my.jar dir/
or mixed
jar -uf my.jar file dir/
jar -u file.jar file1 file2 file3 ...
A JAR file is a ZIP file, remember.
Just use some ZIP library.
Just to add to the existing answers, there is at least one special case: so-called executable JAR files. If you add another JAR file as a dependency -- whether you use jar or zip -- it will complain that the embedded file is compressed:
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/file.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
The solution to this is to use the 0 option to jar:
jar uvf0 myfile.jar BOOT-INF/lib/file.jar
You don't need this for normal class files.
zip file.jar file1 file2 file3
works for me in Mac Os 10.7.5
//Add a file in jar in a particular folder
jar uvf <jar file name> <file to be added> <folder name inside jar>
Extending the existing answers, I find the -C jar option very useful when adding files that are on their own folder and you flatten their path out.
$ jar uf jar-file -C /path/to/my_jars/ this_useful.jar
You will end up having this_useful.jar right in the JAR's root:
$ jar tf jar-file | grep this_useful.jar
this_useful.jar
If someone needs a programmatically answer, here it is.
private static void createJar(File source, JarOutputStream target) {
createJar(source, source, target);
}
private static void createJar(File source, File baseDir, JarOutputStream target) {
BufferedInputStream in = null;
try {
if (!source.exists()) {
throw new IOException("Source directory is empty");
}
if (source.isDirectory()) {
// For Jar entries, all path separates should be '/'(OS independent)
String name = source.getPath().replace("\\", "/");
if (!name.isEmpty()) {
if (!name.endsWith("/")) {
name += "/";
}
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
target.closeEntry();
}
for (File nestedFile: source.listFiles()) {
createJar(nestedFile, baseDir, target);
}
return;
}
String entryName = baseDir.toPath().relativize(source.toPath()).toFile().getPath().replace("\\", "/");
JarEntry entry = new JarEntry(entryName);
entry.setTime(source.lastModified());
target.putNextEntry(entry); in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true) {
int count = in .read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
} catch (Exception ignored) {
} finally {
if ( in != null) {
try { in .close();
} catch (Exception ignored) {
throw new RuntimeException(ignored);
}
}
}
}
Here is another example of copying directory content to JAR file.
/**
* Copy source directory to a folder inside JAR file.
* #param directory
* #param jarFile
* #param jarFolder
* #throws Exception
*/
protected void copyDirectoryToJar(String directory, String jarFile, String jarFolder)
throws Exception {
// Initialize local variables.
FileSystem destinationJarFileSystem = null;
Exception exception = null;
try {
// Get source path.
final Path sourcePath = Paths.get(directory);
// Get destination JAR file system and destination path inside the JAR file.
final URI uri = URI.create("jar:file:/" + jarFile.replace(File.separatorChar, '/'));
final Map<String, String> environment = Map.of("create", "true");
destinationJarFileSystem = FileSystems.newFileSystem(uri, environment);
final Path destinationPath = destinationJarFileSystem.getPath(jarFolder);
// Copy source directory into target JAR file.
copyFromDirToJar(sourcePath, destinationPath, destinationJarFileSystem);
}
catch (Exception e) {
exception = e;
}
finally {
// Close JAR file systems.
try {
if (destinationJarFileSystem != null) {
destinationJarFileSystem.close();
}
}
catch (Exception e) {
if (exception == null) {
exception = e;
}
}
}
// Throw exception.
if (exception != null) {
throw exception;
}
}
/* Recursively copy the source sub directories and files to target JAR file system.
* #param sourcePath
* #param destinationPath
* #param destinationFileSystem
*/
private static void copyFromDirToJar(Path sourcePath, Path destinationPath, FileSystem destinationFileSystem)
throws Exception {
// Create destination directory if it doesn't exist.
if (!Files.exists(destinationPath)) {
Files.createDirectories(destinationPath);
}
// If the source and destination paths designate files, copy the source
// file directly to the destination file.
if (Files.isRegularFile(sourcePath) && Files.isRegularFile(destinationPath)) {
Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
}
// List sub directories in the source path.
Exception [] exception = new Exception [] {null};
Files.list(sourcePath).forEachOrdered(sourceSubPath -> {
try {
Path fileOrFolder = sourceSubPath.getFileName();
Path destinationSubPath = destinationFileSystem.getPath(destinationPath.toString(), fileOrFolder.toString());
// Copy sub directories recursively or copy a single file.
if (Files.isDirectory(sourceSubPath)) {
copyFromDirToJar(sourceSubPath, destinationSubPath, destinationFileSystem);
}
else {
Files.copy(sourceSubPath, destinationSubPath, StandardCopyOption.REPLACE_EXISTING);
}
}
catch (Exception e) {
exception[0] = e;
}
});
// Throw exception.
if (exception[0] != null) {
throw exception[0];
}
}
String cmd = "jar uvf " + "jarName" + " " + "Filename";
System.out.println(cmd);
try {
Process p = Runtime.getRuntime().exec(cmd);
}
catch (Exception ex) {
}
I need to create a temp file, so I tried this:
String[] TempFiles = {"c1234c10","c1234c11","c1234c12","c1234c13"};
for (int i = 0; i <= 3; i++) {
try {
String tempFile = TempFiles[i];
File temp = File.createTempFile(tempFile, ".xls");
System.out.println("Temp file : " + temp.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
The output is something like this:
Temp file : C:\Users\MD1000\AppData\Local\Temp\c1234c108415816200650069233.xls
Temp file : C:\Users\MD1000\AppData\Local\Temp\c1234c113748833645638701089.xls
Temp file : C:\Users\MD1000\AppData\Local\Temp\c1234c126104766829220422260.xls
Temp file : C:\Users\MD1000\AppData\Local\Temp\c1234c137493179265536640669.xls
Now, I don't want the extra numbers (long int) which is getting added to the file name. How can I achieve that? Thanks
First, use the following snippet to get the system's temp directory:
String tDir = System.getProperty("java.io.tmpdir");
Then use the tDir variable in conjunction with your tempFiles[] array to create each file individually.
Using Guava:
import com.google.common.io.Files;
...
File myTempFile = new File(Files.createTempDir(), "MySpecificName.png");
You can't if you use File.createTempFile to generate a temporary file name. I looked at the java source for generating a temp file (for java 1.7, you didn't state your version so I just used mine):
private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
private static final File tmpdir = new File(fs.normalize(AccessController
.doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
static File location() {
return tmpdir;
}
// file name generation
private static final SecureRandom random = new SecureRandom();
static File generateFile(String prefix, String suffix, File dir) {
long n = random.nextLong();
if (n == Long.MIN_VALUE) {
n = 0; // corner case
} else {
n = Math.abs(n);
}
return new File(dir, prefix + Long.toString(n) + suffix);
}
}
This is the code in the java JDK that generates the temp file name. You can see that it generates a random number and inserts it into your file name between your prefix and suffix. This is in "File.java" (in java.io). I did not see any way to change that.
If you want files with specific names created in the system-wide temporary directory, then expand the %temp% environment variable and create the file manually, nothing wrong with that.
Edit: Actually, use System.getProperty("java.io.tmpdir")); for that.
Just putting up the option here:
If someone anyhow need to use createTempFile method, you can do create a temp file and rename it using Files.move option:
final Path path = Files.createTempFile(fileName, ".xls");
Files.move(path, path.resolveSibling(fileName));
You can create a temp directory then store new files in it. This way all of the new files you add won't have a random extension to it. When you're done all you have to do is delete the temp directory you added.
public static File createTempFile(String prefix, String suffix) {
File parent = new File(System.getProperty("java.io.tmpdir"));
File temp = new File(parent, prefix + suffix);
if (temp.exists()) {
temp.delete();
}
try {
temp.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
return temp;
}
public static File createTempDirectory(String fileName) {
File parent = new File(System.getProperty("java.io.tmpdir"));
File temp = new File(parent, fileName);
if (temp.exists()) {
temp.delete();
}
temp.mkdir();
return temp;
}
Custom names can be saved as follows
File temp=new File(tempFile, ".xls");
if (!temp.exists()) {
temp.createNewFile();
}
public static File createTempDirectory(String dirName) {
File baseDir = new File(System.getProperty("java.io.tmpdir"));
File tempDir = new File(baseDir, dirName);
if (tempDir.mkdir()) {
return tempDir;
}
return null;
}