rewrite file instead of recreating a file - java

I have the following piece of code which allows me to recreate a file holding updated data. Even though I used the "StandardOpenOption.TRUNCATE_EXISTING" option to overwrite the old file I was getting an error saying that the file already exists and it wouldn't write on top of it!
File filename = new File("data.txt");
public void writeToFile(char[] data){
filename.delete();
Files.write(filename.toPath(), data, StandardOpenOption.TRUNCATE_EXISTING);
}
Is it possible instead of deleting and recreating the same file over and over to edit the initial file's data?
Thank you
EDIT1: It seems like it was a mistake of mine. Together with "StandardOpenOption.TRUNCATE_EXISTING" I have included "StandardOpenOption.CREEATE_NEW".
This is because I want the file to be created in case it doesn't already exist! How is it possible to first try to edit it and if it doesnt exist create a new one?
Sorry for my initial mistake

The way to go on this one (which worked for me) is creating a try{}catch{} block and within the "try" try to edit the file and if it fails because it doesn't exist create a new file in the "catch".

Look at the JavaDoc of the write method in the Files class, it says: "By default the method creates a new file or overwrites an existing file", so it seems that all you need to do is:
File filename = new File("data.txt");
public void writeToFile(char[] data) throws IOException {
Files.write(filename.toPath(), data);
}

Related

How to prevent file wipe if an error occurs while writing to it?

This is an issue I have had in many applications.
I want to change the information inside a file, which has an outdated version.
In this instance, I am updating the file that records playlists after adding a song to a playlist. (For reference, I am creating an app for android.)
The problem is if I run this code:
FileOutputStream output = new FileOutputStream(file);
output.write(data.getBytes());
output.close();
And if an IOException occurs while trying to write to the file, the data is lost (since creating an instance of FileOutputStream empties the file). Is there a better method to do this, so if an IOException occurs, the old data remains intact? Or does this error only occur when the file is read-only, so I just need to check for that?
My only "work around" is to inform the user of the error, and give said user the correct data, which the user has to manually update. While this might work for a developer, there is a lot of issues that could occur if this happens. Additionally, in this case, the user doesn't have permission to edit the file themselves, so the "work around" doesn't work at all.
Sorry if someone else has asked this. I couldn't find a result when searching.
Thanks in advance!
One way you could ensure that you do not wipe the file is by creating a new file with a different name first. If writing that file succeeds, you could delete the old file and rename the new one.
There is the possibility that renaming fails. To be completely safe from that, your files could be named according to the time at which they are created. For instance, if your file is named save.dat, you could add the time at which the file was saved (from System.currentTimeMillis()) to the end of the file's name. Then, no matter what happens later (including failure to delete the old file or rename the new one), you can recover the most recent successful save. I have included a sample implementation below which represents the time as a 16-digit zero-padded hexadecimal number appended to the file extension. A file named save.dat will be instead saved as save.dat00000171ed431353 or something similar.
// name includes the file extension (i.e. "save.dat").
static File fileToSave(File directory, String name) {
return new File(directory, name + String.format("%016x", System.currentTimeMillis()));
}
// return the entire array if you need older versions for which deletion failed. This could be useful for attempting to purge any unnecessary older versions for instance.
static File fileToLoad(File directory, String name) {
File[] files = directory.listFiles((dir, n) -> n.startsWith(name));
Arrays.sort(files, Comparator.comparingLong((File file) -> Long.parseLong(file.getName().substring(name.length()), 16)).reversed());
return files[0];
}

android create text file on install

I need help storing data on my Android app. I need to create a text file, but only once. I have tried if(file.exists()) and if (file!=null) but nothing's working.I need this text file to store user data strings between app restarts. This code will create the file onCreate everytime, but I need it to only do it if the file doesnt already exist
private void createFile(String filename){
if(memoryFile != null){
memoryFile = new File(getApplicationContext().getFilesDir(), filename);
}
}
This code will create the file onCreate everytime
No, it will not. It will not create any file. It creates an instance of a File object. That is a Java object that represents a (possible) file on the filesystem. It does not actually create the file. To create the file, write something to it, using a FileOutputStream (and a background thread). To see if the file already exists, call exists() on memoryFile.
Also, note that you do not need getApplicationContext() here. Just use getFilesDir().

Files.copy renaming files

Was hoping you could look at some code for me:
public void Copy(Path sourcepath,
Path targetpath) throws IOException {
DateFormat dateFormat = new SimpleDateFormat("yyyymmdd");
File origfile = targetpath.toFile(); // Changes targetpath to file
String name = origfile.getName(); // Gets the name of the file to be updated
File file1 = new File(targetpath.toString() + "." + dateFormat.format(Calendar.getInstance().getTime())); //Create a new file instance with the name of the old file + date
origfile.renameTo(file1); //Rename the original file
origfile.createNewFile(); //Backup the original file
Files.delete(targetpath); //Delete the original file
Files.copy(sourcepath, targetpath);
}
Now everything works, the backing up works and the copying works. My original intention was to rename file being copied to the file being backed up. (hence the string name = origfile.getName();
This was my code:
File file2 = new File(name);
File srcfile = sourcepath.toFile();
srcfile.renameTo(file2);
Now, that worked up to a point, after a while I started getting IOException errors, so after a few hours of struggling. I gave up and just deleted that renaming part.
Lo and behold it still renames the file when being copied.
Now my question: Does Files.copy do it? Is there some mysterious thing happening here? It does EXACTLY what I want it to do, but I am baffled as hell. Why is my code working?
and yes I want to know, in case it breaks or stops working. I can't have something work and not know why!
EDIT:
Sorry was in a bit of a rush when posting, let me pose my question a bit more clearer:
my intention was to have my sourcepath renamed to the original name of the file that is being backed up. I had code to rename it, but it threw an IOException so I deleted it. I only used Files.Copy, so I assumed sourcepath would retain it's original value, and just copy for each instance in a for loop I have. But no, it renames perfectly to the original of each file being backed up. Where and how?
Figured it out! Wooo!
Because I converted the targetpath to a file, backed it up and deleted it this happened:
when I used Files.copy(srcpath,targetpath) srcpath took targetpath's name (the file is deleted but the original path is still there because nothing happened to it)
So basically: two paths were sent to my method, my method created a backup file and deleted the original file (not the path) of the original path. (which would be c:\work\testorigfile e.g.)
Thus when I used Files.copy(srcpath,targetpath) it worked exactly as I wanted it. The answer WAS in the javadoc (in a sense) so thanks for all the tips guys!

Java I/O. delete() method not deleting created file from directory

This code creates a .txt in the folder directory (it works) but when comes the time to delete the whole directory or the .txt file using delete() method, nothing happens.
The delete() method works only when I replace the .txt file with an ordinary folder
import java.io.*;
public class Filemkdir {
public static void main(String[] args) throws Exception {
File f = new File("C:/Temp/Java/secret.txt");
FileWriter fSecret = new FileWriter(f);
f.mkdir();
f.delete();
}
}
On Windows you can't delete an open file. Close the FileWriter first.
Also, the
f.mkdir();
seems completely pointless.
Maybe the fSecret (FileWriter) needs to be closed first. Otherwise the file is "in use"
fSecret.close();
You would basically need to close the writer object before deleting the file
File delete work on file, if you are trying to delete directory you first need to delete all files inside id.
with your code you are giving path for file, but you are creating directory after that.

Force rename a file in Java

Can I use any utility to do a force rename of a file from Java.io?
I understand that Java 7 has these features, but I can’t use it...
If I do a
File tempFile = File.createTempFile();
tempFile.renameTo(newfile)
and if newfile exists then its fails.
How do I do a force rename?
I think you have to do it manually - that means you have to check if the target-name exists already as a file and remove it before doing the real rename.
You can write a routine, to do it:
public void forceRename(File source, File target) throws IOException
{
if (target.exists()) target.delete();
source.renameTo(target)
}
The downside of this approach is, that after deleting and before renaming another process could create a new file with the name.
Another possibility could be therefore to copy the content of the source into the the target-file and deleting the source-file afterwards. But this would eat up more resources (depending on the size of the file) and should be done only, if the possibility of recreation of the deleted file is likely.
You could always delete newFile first:
File newFile = ...
File file = ...
newFile.delete();
file.renameTo(newFile);
I was unable to rename whenever a folder is open. Setting the following property in Java solved my issue:
dirToRename.setExecutable(true);

Categories