Seems a bizarre question, but me and Eclipse have divergent opinions about it. I continue to get the error message java.nio.file.FileSystemException: The process cannot access the file because it is being used by another process
even if the main()
method should have only one thread, one process.
Given a list of files, my program essentially does two things:
- For each and every file, creates a .txt file with information about the file (the .txt is called a "substitute")
- For each and every file, the file is moved into another directory.
If I use comments to execute first the first thing, then the second, nothing untoward happens. The moment in which I try doing both things, one after the other, moving the files returns the aforementioned exception. I have no idea why it happens or how to put an end to it. I hope someone here has ideas.
Here the code. I included all the methods used, including a few written for my custom libraries (usually added to deal with exceptions).
Edit: simplified the code for minimal reproducible example
public static void main(String[] args) {
File[] files = new File[] {
// new File(""),
};
File directoryWhereToPutSubstitutes = new File("");
File directoryWhereToMoveTheOriginalFiles = new File("");
createSubstiteFileForCancelledWav(
directoryWhereToPutSubstitutes,
files,
"The stock appended message to append to the content of each and every substitute. It specifies why the file needs a substitute. "
);
// */ // this method gives problems at the following one
// // the error returned is:
// java.nio.file.FileSystemException: originalFile -> fileDestination: Impossibile accedere al file. Il file è utilizzato da un altro processo.
// Error message in english: The process cannot access the file because it is being used by another process
// TODO | Moving useless file
for(File file : files)
{
System.out.println("MOVING " + file.getAbsolutePath());
/*FileManager.*/moveFile(file, directoryWhereToMoveTheOriginalFiles);
}
}
// =====================================
// TODO | First method
public static void createSubstiteFileForCancelledWav(File directory, File[] files, String appendedMessage) {
int recordNumber, endIndex;
File substitute;
Matcher matcher;
for( File file : files )
if( file.getName().endsWith(".wav") )
{
// Check if the file must be substituted
// If it must be substitutes...
// ...create a txt file with the appropriate name
String nameSubstituteFile = file.getName().substring(0, file.getName().lastIndexOf(".")) + " - substitute.txt";
// ...and put the information of the file in the
createFileAndWriteTextInIt(
directory,
nameSubstituteFile,
recordInformation(file, appendedMessage)
);
}
}
public static void createFileAndWriteTextInIt(File directory, String fileName, String text) {
File file = directory.toPath().resolve(fileName).toFile();
/*FileManager.*/ // createNewFile_nio(file);
if( !Files.notExists(file.toPath(), LinkOption.NOFOLLOW_LINKS) )
System.out.println("THE DESTINATION FILE (" + file.getAbsolutePath() + ") ALREADY EXISTS");
else if( file.isFile() )
{
System.out.println("Trying to create the file " + file.getAbsolutePath() + "...");
// Creates the directories in the file pathname that still do not exist
try { Files.createDirectories(file.toPath().getParent()); } catch (Exception e) { e.printStackTrace(); }
// Creates the file itself
try { Files.createFile(file.toPath()); } catch (Exception e) { e.printStackTrace(); }
}
PrintStream stream = null;
try { stream = new PrintStream(file);
} catch (FileNotFoundException e) { e.printStackTrace(); }
stream.println(text);
stream.close();
}
public static String recordInformation(File file, String appendedMessage) {
StringBuffer support = new StringBuffer();
support.append(/*TestLibraries.*/getFileInfo(file)).append("\n");
support.append("Record line:").append("\n");
support.append(
/*registerLine(isTAC, recordNumber)*/
"In my complete program, the files are not casual: each has a record number, clearly identifiable in the file name, "
+ "and a record line stored in a .txt database. The registerLine() method seeks the record line from the record number, "
+ "but since neither the variable file nor the actual file are involved in any way, shape, or form, "
+ "said method has been omitted in this example. "
).append("\n");
support.append("\n " + appendedMessage).append("\n");
return support.toString();
}
// TODO | Legacy methods from personal libraries - for method 1
public static String getFileInfo(File file) {
StringBuffer support = new StringBuffer();
BasicFileAttributes attrs;
String creationDate = null, lastModificationDate = null, lastAccessDate = null;
try {
attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
FileTime time;
time = attrs.creationTime();
creationDate = simpleDateFormat.format( new Date( time.toMillis() ) );
time = attrs.lastModifiedTime();
lastModificationDate = simpleDateFormat.format( new Date( time.toMillis() ) );
time = attrs.lastAccessTime();
lastAccessDate = simpleDateFormat.format( new Date( time.toMillis() ) );
} catch (UnsupportedOperationException e) { e.printStackTrace(); }
catch (SecurityException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
support.append("Name of file: \t\t" + file.getName() + "\n" );
support.append("Pathname of file: \t\t" + file.getAbsolutePath() + "\n" );
support.append("Creation date: \t\t" + creationDate + "\n" );
support.append("Last modification date: \t" + lastModificationDate + "\n" );
support.append("Last access date: \t\t" + lastAccessDate + "\n" );
if( file.getName().endsWith(".wav") )
{
support.append("File type: \taudio\n");
double seconds = /*AudioInformation.*/getDurationOfWavInSeconds(file),
minutes = seconds / 60, // we obtain the duration in minutes rounded down
hours = minutes / 60; // we obtain the duration in hours rounded down
support.append("Duration: \t"
+ Integer.toString((int) hours) + "h"
+ Integer.toString((int) minutes %60) + "m" // we obtain the number displayed in the 'minutes' section of the duration
+ Integer.toString(((int) seconds)%60 ) + "s \n" // we obtain the number displayed in the 'second' section of the duration
);
String[] lastMod = lastModificationDate
.split(" ")[1].split("-");
long lastModFromMidnight = Integer.valueOf(lastMod[0]) *60*60
+ Integer.valueOf(lastMod[1]) *60
+ Integer.valueOf(lastMod[2]) ;
// Gets the number of seconds from midnight that this file has been started (obtained from: seconds file creation - seconds file length)
seconds = lastModFromMidnight - seconds;
// System.out.println("File: " + file.getName() + " \n\t lastModFromMidnight = " + lastModFromMidnight + ", seconds = " + seconds);
// Converts the above variable in the h-m-s format
minutes = seconds / 60;
hours = minutes / 60;
seconds = seconds % 60;
minutes = minutes % 60;
support.append("Estimated hour of record start: \t"
+ Integer.toString((int) hours) + "-"
+ Integer.toString((int) minutes) + "-"
+ Integer.toString(((int) seconds) ) + " \n"
);
}
return support.toString();
}
public static double getDurationOfWavInSeconds(File file){
AudioInputStream stream = null;
try {
stream = AudioSystem.getAudioInputStream(file);
AudioFormat format = stream.getFormat();
stream.close();
return file.length() / format.getSampleRate() / (format.getSampleSizeInBits() / 8.0) / format.getChannels();
}
catch (UnsupportedAudioFileException e)
{ System.err.println("File: " + file.getAbsolutePath()); e.printStackTrace(); }
catch (IOException e)
{ System.err.println("File: " + file.getAbsolutePath()); e.printStackTrace(); }
finally
{ if(stream!=null)
try { stream.close(); }
catch (IOException ex) { ex.printStackTrace(); } }
return -1;
}
// =====================================
// TODO | Second method - Legacy methods from personal libraries
public static File moveFile(File toBeMoved, File destination, CopyOption... options) {
return moveFile(toBeMoved, destination, toBeMoved.getName(), options);
}
public static File moveFile(File toBeMoved, File directory, String newName, CopyOption... options) {
// Checking conditions
if( directory != null && directory.exists() && directory.isDirectory() )
{
boolean canMove = true;
for(File fileInDestination : directory.listFiles())
if( fileInDestination.getName().equals(newName) )
{
canMove = false;
break;
}
if( canMove )
try {
// Executing action
Files.move( // can cause java.nio.file.FileSystemException: origin -> destin:
// Impossibile accedere al file. Il file è utilizzato da un altro processo.
// Files.copy(
Paths.get(toBeMoved.getAbsolutePath()),
Paths.get(directory.getAbsolutePath()).resolve(newName),
options
);
// Files.delete(toBeMoved.toPath());
return Paths.get(directory.getAbsolutePath()).resolve(toBeMoved.getName()).toFile();
} catch (NoSuchFileException e) { e.printStackTrace(); }
catch (DirectoryNotEmptyException e) { e.printStackTrace(); }
catch (SecurityException e) { e.printStackTrace(); }
catch (FileSystemException e) { e.printStackTrace();
// The following lines have been added so to better analyze what the problem is... with little to no success
System.err.println("Reason for failure:\t" + e.getReason()
+ "\nWhole message:" + e.getMessage());
String s = null;
s.charAt(0);
}
catch (IOException e) { e.printStackTrace(); }
}
return null;
}