How to avoid delete the Temp files using java? - java

I have a simple code to generate the temp files and store the some values(I don't want to store the files in normal storage area)
In future, I want to use that file and get the data from that file (its not a problem if the user manually delete the files).
But I don't want to delete the files automatically. when read this link, I get some information, generally temp files not deleted
when you explicitly call deleteOnExit() but when my JVM finish the work temp file deleted automatically.
//create a temp file
File temp = File.createTempFile("demo_", ".txt");
String path = temp.getParent();
//count the file which names starts with "demo"
File f = new File(path);
File[] matchingFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("demo") && name.endsWith(".txt");
}
});
// Print count array elements
System.out.println("Length : " + matchingFiles.length + " ");
Here I never call the deleteOnExit() (but file delete automtically)OR JVM automatically delete the file? By the way its deleted automatically if is it possible
to avoid deleting the file? or any other ways to do my requirement?

File.createTempFile only creates files with unique names, other than that they are just regular files. They are not deleted automatically. It is explained in File.createTempFile API: This method provides only part of a temporary-file facility. To arrange for a file created by this method to be deleted automatically, use the deleteOnExit method

Related

How to create a file in java without random numbers getting added to the filename and delete after use?

I have to create a temp file in the /tmp directory the code that I am using is adding random numbers to the filename. I have to use the name of the file in order to do something. With the random number, I am not able to use that file. The code I wrote is :
File dir = new File("/tmp");
String prefix = "temp";
String suffix = ".txt";
File tempFile = File.createTempFile(prefix, suffix, dir);
After using the file with the correct file name I also have to delete it how can I do that?
If you need to access the File again, you can store the path of the file to be accessed at another time.
You can get the absolute path file using:
tempFile.getAbsolutePath();
To answer your question about deleting the file after you are finished using it, you can either use the detete() or deleteOnExit() methods of File.
If your code needs a predictable filename, and you want that file to be cleaned up automatically when the program ends, don’t use a temp file (they have a random name - it’s just how they work) but rather just use deleteOnExit() with a regular file:
File file = new File("some/filename.ext");
file.deleteOnExit();

How to lock folder in java before writing file?

I have usecase where multiple thread can write file to a folder. At a given point of time I want to identify which is the latest file in that folder.
Since I cannot use timestamp as it can be same for more than 1 file in the folder. So I want to lock the folder, generate sequence number by counting number of file in folder, write new file by using the generated sequence number, release lock. Is this possible in java?
Similarly while reading take the file with largest sequence number.
Chances of concurrent writing file to a folder is less so performance won't be an issue.
You can't use FileLock on a directory so you will have to handle locking in Java. You could do something like:
private final Object lock = new Object();
public void writeToNext(String dirPath) {
synchronized(lock) {
File dir = new File(dirPath);
List<File> files = Arrays.asList(dir.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return !pathname.isDirectory();
}
}));
int numFiles = files.size();
String nextFile = dir.getAbsolutePath() + File.separator + (numFiles + 1) + ".txt"; // get a path for the new file
System.out.println("Writing to " + nextFile);
// TODO write to file
}
}
Note
You could implement your solution such that each write increments a counter somewhere and you can just use that to get the next value; only order and look for the last file if the counter hasn't been initialized.
Using Java SE 7 or above:
WatchService API allows tracking file operations (create, modify and delete file) in a specified directory. In this scenario create a watch service to track new files created in the specific folder. Each time a new file is created the file creating an event is triggered and the process allows do some user-defined action.
The file already has a created time attribute (java.nio.file.attribute.BasicFileAttributes). This can be extracted as of type java.nio.file.attribute.FileTime which is in millis or can be a more specific java.util.concurrent.TimeUnit (this allows nanosecond precision). This gives a chance to be more specific about what is the newest file.
Also, there is an option to create a custom user-defined file attribute for any file. The attribute allows defining as key-value pair. This unique attribute value can be associated with a file to identify if its the latest. The following APIs allow creating and reading a custom file attribute: java.nio.file.attribute.UserDefinedFileAttributeView and Files.getFileAttributeView().
I think using the above APIs and methods one can create an application to track the latest files created in a specified folder and perform a required action. Note there is no locking mechanism involved if one is using these APIs.
EDIT (included):
Using a collection to retrieve latest file:
A thread-safe collection can be used to store the filenames (or file path) and retrieve them LIFO (last-in-first-out). The watch service (or similar process) can store the filename of the (latest) file created in the folder to this collection. A read operation just gets the latest filename from this collection and work with it. One can consider java.util.concurrent.ConcurrentLinkedDeque or LinkedBlockingDeque based on requirement.
EDIT (included):
A possible solution's process diagram:
Use File.createNewFile() in a loop for writing. Because it
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.
Like this:
import java.io.*;
import java.util.*;
public class FileCreator {
public static void main(String[] args) throws IOException {
String creatorId = UUID.randomUUID().toString();
File dir = new File("dir");
for (int filesCreated = 0; filesCreated < 1000; filesCreated++) {
File newFile;
for (int fileIdx = dir.list().length; ; fileIdx++) {
newFile = new File(dir, "file-" + fileIdx + ".txt");
if (newFile.createNewFile()) {
break;
}
}
try (PrintWriter pw = new PrintWriter(newFile)) {
pw.println(creatorId);
}
}
}
}
Another option would be Files.createFile(...). It throws an exception if the file already exists.
As for reading:
Similarly while reading take the file with largest sequence number.
What's the question here? Just take it.

Delete files using java

In my java application, I'm using FilenameFilter to get zip files in given directory. My directory structure is looks like below.
D\:\MyFiles\data\dir1
D\:\MyFiles\data\dir2
D\:\MyFiles\data\dir3
D\:\MyFiles\data\dir4
zip files are in dir folders. I'm giving only D\\:\\MyFiles\\data to my program and it find folders start with dir using FilenameFilter and then find files ends with zip on dir folders.
Inside a for loop I'm creating new File objects for each zip files and call delete() to delete them, but they aren't deleted.
I have printed file path using getPath() method; output is looks like below.
D\:\MyFiles\data\dir1\a.zip
D\:\MyFiles\data\dir1\b.zip
D\:\MyFiles\data\dir2\b1.zip
D\:\MyFiles\data\dir3\d.zip
Then I manually created a File object as File f = new File("D/:/MyFiles/data/dir1/a.zip") and try to delete. It succeeded.
How can I delete files? How can I give the correct path?
UPDATES
This is the code what I'm using:
// this contains folders start with 'dir' in 'D:\MyFiles\data\'
Vector<String> dirList = utl.identifyDir(conf);
File dir;
for (int i = 0; i < dirList.size(); i++) {
// in my properties file ITEM_FOLDER is written as ITEM_FOLDER=D\:\\MyFiles\\data
// LOG.fine(conf.readConfig(Configuration.ITEM_FOLDER)); returns D:\MyFiles\data
dir = new File(conf.readConfig(Configuration.ITEM_FOLDER)
+ File.separator + dirList.get(i));
// this contains all the files ends with 'zip' in 'dir' folders in 'D:\MyFiles\data\'
Vector<String> zipFiles = utl.identifyZipFiles(dir);
for (int x = 0; x < zipFiles.size(); x++) {
/* delete */
File sourcePath = new File(
conf.readConfig(Configuration.ITEM_FOLDER)
+ File.separator + dirList.get(i)
+ File.separator + zipFiles.get(x));
boolean sp = sourcePath.delete();
LOG.fine("sourcePath : " + sourcePath.getPath() + " : "
+ sp);
// one of LOG prints is D:\MyFiles\data\dir3\d.zip : false
}
}
After reading your update, I think there are 2 possible things going on here.
You've still got something open in your application. You don't happen to use a FileInputStream or anything?
Another process is keeping the .zip busy. Did you open that file? Try closing the explorer window or something like that.
EDIT: A checklist from an other user:
Check that you've got the path correct, e.g. what does file.exists() return?
Check that you've got permission to delete the file as the user running your application
Check that you haven't got an open handle to the file within your code (e.g. have you just read from it and not closed the input stream?)
Check that you don't have the file opened in a desktop app
When you create a new File-object to test, something is different then when you use getPath. Notice how all the slashes in the pathname are \ instead of /.

How to retrieve every file in the Internal Storage?

In Android, assuming that I have files in "/data/data/package.name/", without knowing the names or how many files exist, what is the best way to retrieve/iterate them all?
Also, the name is numerical only.
It looks like you want to list all of the files in the directory, and (possibly) recurse if a file is a directory.
You can find how to do this at the answer to this question.
Copy-pasted:
File f = new File("/data/data/package.name/");
File[] files = f.listFiles();
for (File inFile : files) {
if (inFile.isDirectory()) {
// is directory; recurse?
} else {
doLogicFor(inFile);
}
}

changing location of temp files created using Apache POI

I am stuck with an issue with reading .xlsx file. Some temporary files with random name are created under /tmp/poifiles directory whenever I use WorkbookFactory.create(inputStream);. This directory is created with RW-R-R- permission for the first user. So another user on the same machine when tries to access these files, he CANNOT.
Please suggest me any way
1) How can I create these temp files under /tmp directory and not always in /tmp/poifiles (I am using RHEL V5.0)
2) and how can I configure POI such as to change the location from where it reads the temporary files??
Anymore help to solve my problem of different users accessing same .xlsx files through POI is badly needed.
Yuppie...I got the solution....
POI uses the following method to create temp files.
public static File createTempFile(String prefix, String suffix)
{
if (dir == null) {
dir = new File(System.getProperty("java.io.tmpdir"), "poifiles");
dir.mkdir();
if (System.getProperty("poi.keep.tmp.files") == null) {
dir.deleteOnExit();
}
}
File newFile = new File(dir, prefix + rnd.nextInt() + suffix);
if (System.getProperty("poi.keep.tmp.files") == null) {
newFile.deleteOnExit();
}
return newFile;
}
Now here as we can see it gets the location from property "java.io.tmpdir" and creates poifiles directory inside that...
I changed the location of java.io.tmpdir by setting this property (using System.setProperty("java.io.tmpdir", "somepath"))to user specific location..and Voila....Every user now can create temp files at location always accessible to them and not only the first user gets the privilege to create directory accessible only to him ...!!!
Here is how you can change the location from where POI reads the temporary files programmatically if you are not able to change system property "java.io.tmpdir"
File dir = new File("somepath");
dir.mkdir();
TempFile.setTempFileCreationStrategy(new DefaultTempFileCreationStrategy(dir));
This is driven by the Apache POI TempFile and DefaultTempFileCreationStrategy helper classes.

Categories

Resources