Renaming Files renameTo() workaround Java - java

The following code file.renameTo(new File(newPath)); dosen't rename all the files properly it skips over some I have even used Files.move(file.toPath(), Paths.get(newPath)); but i get an exception error in eclipse saying java.nio.file.FileAlreadyExistsException which i think is occurring because there are sets of files that when they are cut off they will have the same name is there a way to bypass this error in eclipse or fine tune the renameTo()?
I also have tried .substring(0,22);, name.replaceFirst("-2017.*", ""); and
name.substring(0, file.getName().indexOf("-2017") same result.
example:
orginal file name: 3-M-ALABAMA-SUIQUARTER2-2017200346-CD6140
Console Output: 3-M-ALABAMA-SUIQUARTER2
some of Files in folder unchanged: 3-M-ALABAMA-SUIQUARTER2-2017200346-CD6140
for(File file:filesInDir) {
String name = file.getName().substring(0, file.getName().indexOf("-2017"));
String newName = name;
System.out.println(newName); // prints prints to file
String newPath = absolutePathOne + "\\" + newName;
file.renameTo(new File(newPath));
or
Files.move(file.toPath(), Paths.get(newPath));

You can not rename a particular file to a file name that already exists within the folder you are renaming the file in. IMHO ... Even if you can, you shouldn't for a bunch of common sense reasons.
In other words, if we have a folder (directory) named: All_My_Files and in this folder we have two text files, one is named MyFile-2016.txt and the other is named MyFile-2017.txt. Now, we want to rename each of these two files so that the dash and the year (ie: -2016 or -2017) from each file name no longer exists. Essentially what you will end up trying to do is have both file names be MyFile.txt which is not allowed. Your first rename will be fine since on the first go at it there is no file within the folder named MyFile.txt but once the second rename attempt is done on the second file name it's simply going to fail since the name MyFile.txt already exists within that folder which was done from the first rename attempt. This not a code problem, this is an issue with the local file system. Those are the rules of the local file system (No file can have the same name within the same folder). Look at the file names you are going to rename, are there any that will actually create the very same file name once you remove the unwanted text? If there are then those will fail to rename.
The same applies to Moving files. You can not move a file to a folder (directory) that already contains a file with the very same name. The file system rule above applies. You can however overwrite the existing duplicate file name within the destination path if it exists during a move if you tell the Files.move() method to do so:
Files.move(sourcePathAndFileName, destinationPathAndFileName,
StandardCopyOption.REPLACE_EXISTING);
You will need to import:
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
Keep in mind though, before you blatantly overwrite an existing file you better make pretty sure that this is what you want to do. Prompting the User to carry out an overwrite would be a normal course of action but doesn't necessarily need to be the case for specific in house operations.

Related

How & What does the delete method for a file actually delete?

Suppose I create a txt file and save it as "Untitled1". I enter eclipse and type the following:
import java.io.*;
public class Test {
public static void main(String[] args){
File f = new File("Untitled1.txt");
boolean isDeleted = f.delete();
System.out.println(isDeleted);
}
}
False was returned from the delete method indicating the file was not deleted. I understand that a file object represents the location of a file and NOT the contents of the file. But then what is actually being deleted? How do you delete a location of a file, without deleting the contents of a file itself?
I also entered the file Path for the Untitled1 file as a parameter to the File objects constructor, that did not delete the Untitled1.txt file either.
A file is identified by its path through the file system, beginning from the root node.
Representation of the path depends on the system. e.g. in windows C:\foo\bar while in linux /home/foo/bar.
So in below code, string path would be converted into abstract pathname and it would create the File instance and when you call the delete method it will try to delete the node. Basically content and path are not really different.
File f = new File("Untitled1.txt");
So, the file itself is deleted. False could be returned for a variety of reasons.
public boolean delete()
Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted.
Note that the Files class defines the delete method to throw an IOException when a file cannot be deleted. This is useful for error reporting and to diagnose why a file cannot be deleted.
Returns:
true if and only if the file or directory is successfully deleted; false otherwise
Throws:
SecurityException - If a security manager exists and its SecurityManager.checkDelete(java.lang.String) method denies delete access to the file
Catch the SecurityException and you will probably find that you are disallowed from directly deleting the file programmatically.
First, please note that File is an old, bad class, that should not be used nowadays.
It's a lot better to use the Files class, more specifically its delete method.
As for what exactly is deleted: a file is a bunch of bytes that sits in a hard disk. The disk - or one of its partitions - is formatted into a filesystem, which is a data structure that organizes directories and files. The particular filesystem dictates how the file is broken up into pieces, how these pieces can be located or added by operations such as seek, read, write etc.
A filesystem has directories, which give you start points for the files. The file path in the hierarchy of directories tells the system where to find the file, including all its information (like pointer to its start, read/write permissions, etc.) The information in the directory that tells where the actual file contents is is sometimes called a "link" (at least in Unix file systems).
When you delete a file, the usual thing that happens is that the particular link to that file from that directory is removed. If that is the last link (the file can be linked from more than one directory, at least in some file systems), the blocks that belong to the file are also marked as free so that they can be allocated to another file.
So your File object tells the system where the file is, but the delete operation ultimately tells the system both to unlink the file from the directory (the penultimate part of the path), and if that's the last link, it also tells the system to go to the file contents and mark it as free.
This is a general description. The exact details and what happens when the content is marked as free is dependent on the particular filesystem used (e.g. ext4,reiserFS... (Linux), HFS+ (MacOS X), NTFS,FAT32... (Windows)).

How to create a Path and a File that does not Exist in Java

This is the problem I have: If part or all of the path does not already exist, the server should create additional directories as necessary in the hierarchy and then create a new file as above.
Files.createDirectories(path);
That's what I am currently using, but it does not create the end file. For example is the path="/hello/test.html" it will create a directory called "hello" and one called "test.html", I want the test.html to be a file. How can I do that?
This is what I did to solve this "problem" or misuse of the libraries.
Files.createDirectories(path.getParent());
Files.createFile(path);
The first line will get the parent directory, so lets say this is what I want to create "/a/b/c/hello.txt", the parent directory will be "/a/b/c/".
The second like will create the file within that directory.
Have you looked at the javadoc? createDirectories only creates... directories. If you're intent on using Files.createDirectories, parse off the file name, call createDirectories passing only the path portion, then create a new file passing the entire path. Otherwise this is a better approach.
Files.createDirectories(path.substring(0, path.lastIndexOf(File.separator)+1));
File yourFile = new File(path);
you can parse the 'path' variable to isolate the file and the directory using delimiter as '/', and do File file = new File(parsedPath); This would work only when you know that you ALWAYS pass the file name at the end of it.
If you know when you are a) creating a directory b) creating a directory and file, you can pass the boolean variable that would describe if file needs to be created or not.

Why is directory name which contains dot(s) in the end is treated as a directory even if doesn't exists using File object in Java?

I have a directory which contains several files and directories. I am writing a small java program which displays the files present in a the directory supplied as a parameter.
The problem I am facing is when I append dot(s) after a directory name, it is being treated as existing even if the directory is not present. To further clarify, suppose I have a directory named "abc" which exists. It works fine when I enter "abc". But when I enter the directory name as "abc...", even then also the directory is being treated as it exists. I want to avoid it. I am creating a FIle object using
File directory = new File( fileName );
if ( directory.exists() ) {
// do something
}
Any suggestions how can I avoid it?
This is unrelated to Java, it's a Windows thing: Trailing dot(s) are removed from file and folder names. Even C/C++ programs can't do it.
As a workaround, try to use the prefix \\?\:
File dir = new File( "\\\\?\\" + path );
But this will disable a lot of other things like relative paths and slash conversion.
Related answers:
How to create a filename with a trailing period in Windows?
MSDN Naming Files, Paths, and Namespaces
Why doesn't Explorer let you create a file whose name begins with a dot?

File not found?

I have an assignment and we have a couple of classes given, one of them is a filereader class, which has a method to read files and it is called with a parameter (String) containing the file path, now i have a couple of .txt files and they're in the same folder as the .java files so i thought i could just pass along file.txt as filepath (like in php, relatively) but that always returns an file not found exception!
Seen the fact that the given class should be working correctly and that i verified that the classes are really in the same folder workspace/src as the .java files i must be doing something wrong with the filepath String, but what?
This is my code:
private static final String fileF = "File.txt";
private static final ArrayList<String[]> instructionsF =
CreatureReader.readInstructions(fileF);
Put this:
File here = new File(".");
System.out.println(here.getAbsolutePath());
somewhere in your code. It will print out the current directory of your program.
Then, simply put the file there, or change the filepath.
Two things to notice:
check if "File.txt" is really named like that, since it won't find "file.txt" -> case sensitivity matters!
your file won't be found if you use relative filenames (without entire directory) and it isn't on your classpath -> try to put it where your .class files are generated
So: if you've got a file named /home/javatest/File.txt, you have your source code in /home/javatest/ and your .class files in that same directory, your code should work fine.
If you class is in package and you have placed the files as siblings then your path must include the package path. As suggested in other answers, print out the path of the working directory to determine where Java is looking for the file relative from.

Using File to create directory which contains periods

File testDir = new File("C:\temp\test");
testDir.createNewFile();
As I understand it, the above will create a directory called test in the directory c:\temp
File testDir = new File("C:\temp\test.dir");
testDir.createNewFile();
As I understand it, the above will create a file called test.dir in the directory c:\temp
What should I be doing to the code above if I wish for test.dir to actually be a directory?
No, the first one will create a regular file - after all, that's what you asked it to do:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
Nothing there says it will create a directory. You'll want to escape the backslashes though, or it's trying to find C:<tab>emp<tab>est
If you want to create a directory, use File.mkdir or File.mkdirs(). You'll still need to escape the backslashes:
File testDir = new File("C:\\temp\\test.dir");
bool created = testDir.mkdir();
(Use mkdirs to create parent directories as well.) The return value tells you whether or not it actually created a directory.
That's not true.
File.createFile() will create a file.
File.mkdir() creates a directory.
http://download.oracle.com/javase/6/docs/api/java/io/File.html
File testDir = new File("C:\temp\test");
testDir.createNewFile();
As I understand it, the above will
create a directory called test in the
directory c:\temp
Wrong - it will create file called "test". Files do not have to have a "filename extension".
To create a directory:
testDir.mkdir();
BTW, this kind of question is most easily and quickly answered by looking at the API doc. Do yourself a favor and get familiar with it.

Categories