I am using apache util to copy a file to a directory using the fileutil.copyFile(src, dest)
The file I am copying is updated every 2 seconds by an external vendor and I really do not want to lock it (my application is running in windows- this will cause all sorts of problems). I am hoping someone might be able to help me in advising what is the safest way to copy or even read a file without the source file getting locked?
Kind regards
Here is the method that can be used to copy a file using FileChannel. Apache Commons IO FileUtils. copyFile(File srcFile, File destFile) can be used to copy file in java. If you are already using Apache Commons IO in your project, it makes sense to use this for code simplicity.
copyFileToDirectory() is a static method of the FileUtils class that is used to copy a file to a directory, with the option to preserve the filing date. This method copies the contents of the specified source file to a file of the same name in the specified destination directory.
Another common way to copy a file with Java is by using the commons-io library. The latest version can be downloaded from Maven Central. Then, to copy a file we just need to use the copyFile() method defined in the FileUtils class. The method takes a source and a target file.
You can move a file or directory by using the move(Path, Path, CopyOption...) method. The move fails if the target file exists, unless the REPLACE_EXISTING option is specified. Empty directories can be moved.
Because you are not explicitly locking the entire file before the copy action the default os file locking mechanism is at work.
I ran a quick test program to see what happens on a Windows machine when you copy a source file while an external process is writing to the file every 2secs.
The process that writes to the file never encountered a problem.
public static void main(String[] args) {
File f = new File("..\\test.txt");
long startTime = System.currentTimeMillis();
long elapsedTime = 0;
while (elapsedTime < 1000 * 60) {
try {
FileUtils.writeStringToFile(f, System.currentTimeMillis()+" : Data Write\r\n", true);
Thread.sleep(2000);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex){
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
elapsedTime = System.currentTimeMillis() - startTime;
}
}
The process that copies the file will throw an exception if it does not finish the copy before the source file changes length. It appears that this exception is more of a warning that the copied version of the file is incomplete. When I synced timing to keep from reading from the file at the same time writing happens this exception was not thrown.
public static void main(String[] args) {
File f = new File("..\\test.txt");
long startTime = System.currentTimeMillis();
long elapsedTime = 0;
while (elapsedTime < 1000 * 60) {
try {
FileUtils.copyFile(f, new File("..\\test\\test.txt"));
Thread.sleep(2000);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex){
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
elapsedTime = System.currentTimeMillis() - startTime;
}
}
Based on this test I would not worry about what happens to the writing process. I would do something to handle the case when java.io.IOException: Failed to copy full contents from '..\test.txt' to '..\test\test.txt'
is thrown.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With