The .delete() method in java is not working - java

Files inside the (Tracks)directory was not deleted. The method deletes the wav files stored in the directory.
public boolean deleteTrack(response) {
ListIterator<Track> trackListIterator = this.trackList.listIterator();
//tracklist is the linked list on which I'm using list iterator. I'm storing song which is a object inside it. this object has a fn() that returns content root path not absolute path.
String path = "";
while (trackListIterator.hasNext()) {
//RESPONSE == PARAMETER
if (trackListIterator.next().getTrackName().equals(response)) {
trackListIterator.previous();
path = trackListIterator.next().getTrackPath();//this is the fn() that
returns content root path example(src/Exploit/org/Trackstore/Music/Action Movie Music-FesliyanStudios.wav).
break;
}
}
File file = new File(path);
//here I'm taking absolute path for deleting actual wav file from the computer.
File toBeDeleted = new File(file.getAbsolutePath());
return toBeDeleted.delete();// returns false everytime.
}

The old API has many issues. For example, most methods return a boolean to indicate the result which is stupid and unjavalike - fortunately, there is a new API that fixes these issues.
Use it and you'll know WHY it failed. If that's too much effort, well, there isn't much to say. It didn't delete. No idea why, and there's no way to ask that API about why.
The new API lives in the java.nio.file package.
Replace this:
File f = new File("path/to/file");
if (!f.delete()) { ... it didn't work ... }
with:
Path p = Paths.get("path/to/file");
try {
Files.delete(p);
} catch (IOException e) {
// the exception will explain everything there is to be said about why it did not work!
}

Related

File Handling issue in Multi threaded Environment

I am facing a strand kind of issue in multi threaded environment.
Though this code was pretty old and was working since long time.
One of the person complained that they are facing issue like. Even
though the file created by one thread exist , another thread saying no
file exist.
I providing a sample method where the problem is coming..
/**
* Creates a temporary directory. Will be deleted when the program closed if it
* is empty!
*
* #return the temporary directory
* #throws com.osm.exception.WMException if there is a problem
*/
public static File createTempDir() throws WMException {
synchronized (pdm.semaphore) {
try {
final File parent = WMSession.getWMSession().getRootTempDir();
if (!parent.exists()) {
throw new IllegalStateException(parent + " does not exist"); //frozen
}
final File tmpDirectory = File.createTempFile("WMTempDir", "", parent); //frozen
tmpDirectory.delete();
tmpDirectory.mkdirs();
logFileCreated(tmpDirectory);
return tmpDirectory;
} catch (final IOException ioe) {
throw new WMException(ioe);
}
}
}
This code is being called from another method code as below.
void copy_from_db2_using_temp_dir(String phys_name, int storage_type, int store_date, int file_flag,
String directory, String file_name) throws WMException {
final File destDir = new File(directory);
if (!destDir.exists()) {
// no conflict possible since destination directory does not yet exist.
pdm.copy_from_db2(phys_name, storage_type, store_date, file_flag, directory, file_name);
return;
}
final File tmpDir = WMFile.createTempDir();
final File tmpDestFile = new File(tmpDir, file_name);
final File destFile = new File(directory, file_name);
try {
final boolean destFileExistsFlag = destFile.exists();
if (destFileExistsFlag && (file_flag != DEL_OLD)) {
final String msg = pdm.fix_mesg(pdm.catgets("data_mgr", 266, "*** ERROR: Cannot overwrite file '{1}'"),
destFile.getAbsolutePath());
throw new WMException(msg);
}
pdm.copy_from_db2(phys_name, storage_type, store_date, file_flag, tmpDir.getAbsolutePath(), file_name);
if (tmpDestFile.isFile() && destFile.isDirectory()) {
final String msg = pdm.fix_mesg(pdm.catgets("data_mgr", 269, "*** ERROR: Could not remove file '{1}'"),
destFile.getAbsolutePath());
throw new WMException(msg);
}
moveFiles(tmpDestFile, destFile, (file_flag == DEL_OLD));
} finally {
deleteTempDir(tmpDir);
}
}
The another thread/process always getting the condition
!parent.exists() true. Which is incorrect as it must get the parent
file.
Need suggestion input or any logging that will helpful to know if the
invocation has some issue or some issue in the code.
I got something on StackOverflow but not sure if that is relevant
here.
File.exists() issue in multi threaded env
if (!parent.exists()) { in your createTempDir function is triggered, because the parentFolder of the file that you are trying to create does not exist. This has nothing to do with multithreading.
Example:
Lets say we are trying to create the folder C:\myGame\logs in the createTempDir method. Your code will first test to see if C:\myGame exists. If it does not exist, then your code will throw an illegal state exception and not continue execution.
In other words: the parent directory in which you want to create your logs directory does not exist. This could be due to a number of reasons:
WMSession.getWMSession().getRootTempDir() is not properly configured: it points to a wrong filepath.
Perhaps you don't even need to assert that the parent directory exists. Because you call mkdirs() in your code, all required ancestor-directories for your logs directory will be automatically created.
You can consider the following solutions:
Properly configure WMSession so that it points to the correct folder, assuming that you want the parent directory to exist in advance of your code execution.
Simply don't care about if the parent directory exists, as mkdirs handles this for you.

Files.copy not recognising binary files on Windows (Java)

So I am trying to copy some files with Files.copy(), and while it is working fine in Mac, and works to copy text files on Windows, when I try to copy a binary file I just get the error:
java.nio.file.NoSuchFileException: C:\path\to\file
My function is:
private void copyFiles()
{
ArrayList<String> temp = new ArrayList<>(); //This is set up outside the function
temp.add("file1");
temp.add("file2"); //etc
String AlphaSimFileName = "folderName"; //This is actually set outside the function
String currentDir = System.getProperty("user.dir");
Path baseAlphaName = Paths.get(currentDir, AlphaSimFileName);
Path baseDirectoryName = Paths.get(currentDir, name);
System.out.println(""+baseAlphaName.toString());
System.out.println(""+baseDirectoryName.toString());
// for (String l: MyFunctions.getFilesAsString()) //gives the list of files to copy.
for (String l: temp)
{
Path p1 = Paths.get(baseAlphaName.toString(), l);
Path p2 = Paths.get(baseDirectoryName.toString(), l);
try
{
Files.copy(p1, p2, StandardCopyOption.REPLACE_EXISTING);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Anyone have any idea why this is happening?
(Posted on behalf of the OP).
The reason for this was that Windows was automatically hiding file extensions, so the file that I was trying to move (i.e. without the extension) didn't exist.
Try doing it manually first. Use \\ instead of \ when you hardcode the path for Windows using Java. Also, the file extension may be missing.

Java read file within static method, using ClassLoader gives FileNotFoundException

I want to read a file in my java class. My question is similar to this one, but there are two differences. first, I use a different project layout:
/src/com/company/project
/resources
In the resources folder I have a file called "test.txt":
/resources/test.txt
In the project folder I have a class test.java
/src/com/company/project/test.java
I want mu java class to be able to read the contents of test.txt in a STATIC METHOD. I've tried the following:
private static String parseFile()
{
try
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String fileURL = classLoader.getResource("test.txt").getFile();
File file = new File(fileURL);
...
}
}
and the following paths:
File file1 = new File("test.txt");
File file2 = new File("/test.txt");
File file3 = new File("/resources/test.txt");
But they all throw a FileNotFoundException when I want to read the file. How can I correctly declare the path to my file in the snippet above with respect to my project setup and the fact that the method needs to be static?
You should use the class loader of the class which is in the same JAR as the resource instead of the TCCL. And then you need to specify the name of the resource with a full path. And it is typically not good to access those as files. Just open it directly for read (or copy it to a temp file if you need to):
InputStream is =
Project.class.getClassLoader().getResourceAsStream("/resource/test.txt");
BTW: if you simply want to open a file, you need to use a relative file name. This is searched relative to the start dir, which is normally the project main dir (in eclipse):
File resource = new File("resource/test.txt");
(but this wont work if you package it up as a JAR).
After endless trials, I gave up on ClassLoader and getResource methods of any kind.
Absolutely nothing worked, especially if the opening attempt was made from another project. I always ended up getting the bin folder instead of the src folder.
So I devised the following work around:
public class IOAccessory {
public static String getProjectDir() {
try {
Class<?> callingClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
URL url = callingClass.getProtectionDomain().getCodeSource().getLocation();
URI parentDir = url.toURI().resolve("..");
return parentDir.getPath();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return "";
}
}
The getProjectDir method returns the physical path of the project from which it was called, e.g. C:/workspace/MyProject/.
After that, all you need to do is concatenate the relative path in MyProject of your resource file to open the stream:
public void openResource() throws IOException {
InputStream stream = null;
String projectDir = IOAccessory.getProjectDir();
String filePath = "resources/test.txt";
try {
stream = new FileInputStream(projectDir + filePath);
open(stream);
} catch(Exception e) {
e.printStackTrace();
} finally {
if (stream != null)
stream.close();
}
}
This technique works whether the openResource method is static or non-static, and whether it is called from within the project or from another project on the build path.
It really depends on how your IDE generates output from your project. Typically, classloaders load resources relative to the invoking classes, but if treated right, 'resources' will just end up in the 'root' of your output folder hierarchy, and you can access them accordingly.
For example, if I recreate your code in IntelliJ IDEA, in a class called com/acme/TestClass.class, the following output structure is generated within the IDE when building. This assumes I have "test.txt" sitting in a folder I called "resources", and that folder is specified as being a "resources root":
/com
/acme
TestClass.class
test.txt
The text file ends up in the output folder's root, so accessing it is simple. The following code works for me when I attempt to load the file in a static method within TestClass:
ClassLoader cl = TestClass.class.getClassLoader();
InputStream is = cl.getResourceAsStream("test.txt");
The only thing not covered in the other answers is that your URL conversion to file might not work correctly. If the directories above your project contain a characters that must be decoded then your call to 'getResource("test.txt").getFile()' is not giving you a valid java.io.File path.
I load shader for openGL ES from static function.
Remember you must use lower case for your file and directory name, or else the operation will be failed
public class MyGLRenderer implements GLSurfaceView.Renderer {
...
public static int loadShader() {
// Read file as input stream
InputStream inputStream = MyGLRenderer.class.getResourceAsStream("/res/raw/vertex_shader.txt");
// Convert input stream to string
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String shaderCode = s.hasNext() ? s.next() : "";
}
...
}
Another method to convert input stream to string.
byte[] bytes;
String shaderCode = "";
try {
bytes = new byte[inputStream.available()];
inputStream.read(bytes);
shaderCode = new String(bytes);
}
catch (IOException e) {
e.printStackTrace();
}

Iterating through a directory in java

Hi right now I have the following method I am using to read one file at a time in a the same directory as the class that has this method:
private byte[][] getDoubleByteArrayOfFile(String fileName, Region region)
throws IOException
{
BufferedImage image = ImageIO.read(getClass().getResource(fileName));
byte[][] alphaInputData =
new byte[region.getInputXAxisLength()][region.getInputYAxisLength()];
for (int x = 0; x < alphaInputData.length; x++)
{
for (int y = 0; y < alphaInputData[x].length; y++)
{
int color = image.getRGB(x, y);
alphaInputData[x][y] = (byte)(color >> 23);
}
}
return alphaInputData;
}
I was wondering how I can make it so that instead of having "fileName" as a argument I can but a directory name as a argument and then iterate through all of the files within that directory and perform the same operation on it. Thanks!
If you are using Java 7, then you need to take a look at NIO.2.
Specifically, take a look at the Listing a Directory's Contents section.
Path dir = Paths.get("/directory/path");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file: stream) {
getDoubleByteArrayOfFile(file.getFileName(), someRegion);
}
} catch (IOException | DirectoryIteratorException x) {
// IOException can never be thrown by the iteration.
// In this snippet, it can only be thrown by newDirectoryStream.
System.err.println(x);
}
Here is a quick example that may help:
private ArrayList<byte[][]> getDoubleByteArrayOfDirectory(String dirName,
Region region) throws IOException {
ArrayList<byte[][]> results = new ArrayList<byte[][]>();
File directory = new File(dirName);
if (!directory.isDirectory()) return null //or handle however you wish
for (File file : directory.listFiles()) {
results.add(getDoubleByteArrayOfFile(file.getName()), region);
}
return results;
}
Not exactly what you asked for since it's wrapping your old method rather than re-writing it, but I find it a bit cleaner this way, and leaves you with the option of still processing a single file. Be sure to tweak the return type and how to handle the region based on your actual requirements (hard to tell from the question).
It is rather simple, using the File#listFiles() which returns a list of files in the specified File, which must be a directory. To make sure that the File is a directory, simply use File#isDirectory(). The problem occurs where you decide how to return the byte buffer. Since the method returns a 2d buffer, it is necessary to use a 3d byte buffer array, or in this case a List seems to me like the best choice since an unknown number of files will exist in the directory in question.
private List getDoubleByteArrayOfDirectory(String directory, Region region) throws IOException {
File directoryFile = new File(directory);
if(!directoryFile.isDirectory()) {
throw new IllegalArgumentException("path must be a directory");
}
List results = new ArrayList();
for(File temp : directoryFile.listFiles()) {
if(temp.isDirectory()) {
results.addAll(getDoubleByteArrayOfDirectory(temp.getPath(), region));
}else {
results.add(getDoubleByteArrayOfFile(temp.getPath(), region));
}
}
return results;
}
You can, see the list and listFiles documentation for how to do this.
We can use recursion to process a directory with subdirectories also. Here I am deleting file one by one, you can call any other function to process it.
public static void recursiveProcess(File file) {
//to end the recursive loop
if (!file.exists())
return;
//if directory, go inside and call recursively
if (file.isDirectory()) {
for (File f : file.listFiles()) {
//call recursively
recursiveProcess(f);
}
}
//call processing function, for example here I am deleting
file.delete();
System.out.println("Deleted (Processed) file/folder: "+file.getAbsolutePath());
}

Check if file exists without creating it

If I do this:
File f = new File("c:\\text.txt");
if (f.exists()) {
System.out.println("File exists");
} else {
System.out.println("File not found!");
}
Then the file gets created and always returns "File exists". Is it possible to check if a file exists without creating it?
EDIT:
I forgot to mention that it's in a for loop. So here's the real thing:
for (int i = 0; i < 10; i++) {
File file = new File("c:\\text" + i + ".txt");
System.out.println("New file created: " + file.getPath());
}
When you instantiate a File, you're not creating anything on disk but just building an object on which you can call some methods, like exists().
That's fine and cheap, don't try to avoid this instantiation.
The File instance has only two fields:
private String path;
private transient int prefixLength;
And here is the constructor :
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
As you can see, the File instance is just an encapsulation of the path. Creating it in order to call exists() is the correct way to proceed. Don't try to optimize it away.
Starting from Java 7 you can use java.nio.file.Files.exists:
Path p = Paths.get("C:\\Users\\first.last");
boolean exists = Files.exists(p);
boolean notExists = Files.notExists(p);
if (exists) {
System.out.println("File exists!");
} else if (notExists) {
System.out.println("File doesn't exist!");
} else {
System.out.println("File's status is unknown!");
}
In the Oracle tutorial you can find some details about this:
The methods in the Path class are syntactic, meaning that they operate on the Path instance. But eventually you must access the file system to verify that a particular Path exists, or does not exist. You can do so with the exists(Path, LinkOption...) and the notExists(Path, LinkOption...) methods. Note that !Files.exists(path) is not equivalent to Files.notExists(path). When you are testing a file's existence, three results are possible:
The file is verified to exist.
The file is verified to not exist.
The file's status is unknown. This result can occur when the program does not have access to the file.
If both exists and notExists return false, the existence of the file cannot be verified.
Creating a File instance does not create a file on the file system, so the posted code will do what you require.
The Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don't actually exist.
This can be applied too for Files.noExists, Files.isDirectory and Files.isRegularFile
According this you can use the following :
Paths.get("file_path").toFile().exists()

Categories