Link to home
Start Free TrialLog in
Avatar of EmailSurfer
EmailSurfer

asked on

Using createTempFile() method?

Hello,

I am trying store a number files in a choosen folder, and use the createTempFile to create a unquie filename for each stored.

I would like to start with the filename tmp, then tmp1, tmp2 ect. To achieve this would I need to loop this createTempFile until it finds a unique filename? And could any example what the prefix and suffix values are?

I wondered what value the createTempFile returned?

Thanks

while(){
File file = new File(path + fileName);

if(file.exists()){
   File.createTempFile("Prefix", "Suffix");
}
}
Avatar of Jim Cakalic
Jim Cakalic
Flag of United States of America image

Per the javadoc for File.createTempFile, the method "creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name. If this method returns successfully then it is guaranteed that:
   1. The file denoted by the returned abstract pathname did not exist before this method was invoked, and
   2. Neither this method nor any of its variants will return the same abstract pathname again in the current invocation of the virtual machine."

Also, "the name of the new file will be generated by concatenating the prefix, five or more internally-generated characters, and the suffix."

So temp file names are always unique and guaranteed not to exist when created. AFAIK, there is no way to externally influence the "internally-generated characters" to provide a continuous incrementing value.

You can find out the filename constructed by createTempFile using the File.getName() method.

Jim
For details, please see:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html

The file name is uniquely and randomly generated.

For example:
a) prefix="ABC", suffix="" will generate "ABCxxxxx" where xxxxx is a random number (default 5 digit)
b) prefix="ABC", suffix=null will generate "ABCxxxxx.tmp" where xxxxx is a random number (default 5 digit)
c) prefix="ABC", suffix=".xyz" will generate "ABCxxxxx.xyz" where xxxxx is a random number (default 5 digit)
Avatar of EmailSurfer
EmailSurfer

ASKER

In the api it does not say this method would add a 5 digit number to end of the filename.

File.createTempFile("Prefix", "Suffix");
Would the createTempFile actually create temp files in the folder?

Or just test if the filename with the prefix, and suffix defined in the createTempFile exists?
Hi,

try {
        // Create temp file.
        File temp = File.createTempFile("pattern", ".suffix");
   
        // Delete temp file when program exits.
        temp.deleteOnExit();
   
        // Write to temp file
        BufferedWriter out = new BufferedWriter(new FileWriter(temp));
        out.write("aString");
        out.close();
    } catch (IOException e) {
    }
http://javaalmanac.com/egs/java.io/CreateTempFile.html

R.K
Will the createTempFile() always create a unique file in the folder chosen, on a single run?



>>Will the createTempFile() always create a unique file in the folder chosen, on a single run?

Yes. You could just use the timestamp and then add your 1,2,3 etc to it
>>In the api it does not say this method would add a 5 digit number to end of the filename.
The javadoc says, "the name of the new file will be generated by concatenating the prefix, five or more internally-generated characters, and the suffix."

>>Would the createTempFile actually create temp files in the folder?
No, it doesn't actually create the file. You have to open a FileOutputStream or a FileWriter on the File object returned by createTempFile for a file to actually be created.
To do what you want is something like this:

public class CustomTempFile {
    private static File tempDir = new File(System.getProperty("java.io.tmpdir"));
    private static DecimalFormat seqFmt = new DecimalFormat("00000");

    public static File createTempFile(String prefix, String suffix) {
        return createTempFile(prefix, suffix, tempDir);
    }

    public static File createTempFile(final String prefix, String suffix, File directory) {
        if (suffix == null) {
            suffix = ".tmp";
        }
        if (directory == null) {
            directory = tempDir;
        }
        String[] files = directory.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.startsWith(prefix);
            }
        });
        int sequence = 1;
        if (files != null && files.length > 0) {
            Arrays.sort(files);
            String last = files[files.length - 1];
            sequence = 1 + Integer.parseInt(last.substring(prefix.length(), last.indexOf(suffix)));
        }
        synchronized (seqFmt) {
            return new File(directory, prefix + seqFmt.format(sequence) + suffix);
        }
    }
}

Then, instead of calling File.createTempFile, call CustomTempFile.createTempFile.

Jim
Thanks

To tell the createTempFile method where to store the files, would I use:

File path = new File("/files/userfolder/");

File.createTempFile("tmp", extension, path);
Use this

>>private static File tempDir = new File(System.getProperty("java.io.tmpdir"));

as Jim says
Of course, you can put them wherever you want. The System property java.io.tmpdir just happens to be the default place where the JVM wants to create temp files. But if you want them created in a specific directory then do as you suggested.
My aim in using the createTempFile method was to store files in a particular folder each with a unquie filename.

Rather than storing the file created by the createTempFile method in the default temp folder. I through the temp file should be stored in the user folder I am using?

>>My aim in using the createTempFile method was to store files in a particular folder each with a unquie filename.

Well that's not *really* a temp file then. Temp files should be in the temp directory and be considered only valid for the lifetime of the application.

You can create the files if they're longer lasting than that wherever you want as long as you have write permissions. <user.home>/x would be good for that
I am still a little unclear about the createTempFile use.

My program has an array of 3 files, and I wish to store these in a userfolder which might already contain files.

I was trying to find some way of storing the files in the folder so each has a unquie filename. And then store the orginal filename in an xml or database.

I have the filename and extension of each file. I thought the createTempFile method automatically added a number to the end of a filename to make it unquie.
I thought I could use:

File newFile = currentFile.createTempFile(tmp, extension);

and if the orginal file was called test.jpg

The result of the createTempFile would be tmpxxxxx.jpg

Where the xxxxx is the random number added by the createTempFile method.
>>I was trying to find some way of storing the files in the folder so each has a unquie filename.

Making a unique name is really quite trivial, operating on a probabilistic basis, and then you can always check if it already exists.
Is the createTempFile method not the best to use in this case
Probably not, since you don't really have much control over the name created (since that's of no importance to that method)
If the currentFile File variable contained test.jpg

And the File varaible path contain \files\userfolder\

File newFile = currentFile.createTempFile(tmp, extension, path);

Would the result of the createTempFile method not be a file created in the folder \files\userfolder with a unquie filename to anyother in that folder.

And then I can write the file to this temporary file in the folder?

Thanks

ASKER CERTIFIED SOLUTION
Avatar of Jim Cakalic
Jim Cakalic
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks

Would you think the use of the createTempFile, would be a better approach an taking a filename for example test.jpg

And creating a new filename for this for example

tmp + java-calulated-milli-seconds +.jpg

Well from your earlier posting i thought some sort of sequence number was required ...
You know, "better" is a question of which meets your needs/requirements. Someone brought up previously the question of how long these "temp" files are to exist. If the idea is that they will exist for extended periods of time (weeks or more) across several JVM restarts, then it might be better to implement a specific naming convention rather than to rely on the default scheme of File. For one thing, you're limited to 99,999 temp files. Maybe that's not a problem. Also, and I could be wrong here, I seem to recall that the more temp files in a single directory the greater the chance of collision so that createTempFile potentially takes longer the more files exist.

Creating a custom temporary file naming facility isn't very difficult as I demonstrated in a previous post. You could easily modify what I did to create a name that included the System.currentTimeMillis instead of a sequence number as was originally requested. Be aware thought that System.currentTimeMillis might change however (system clock drifts and gets resync'd with time service or daylight savings time change) or might have a resolution too coarse for your needs (Sun's Windows JVM has a resolution of 10ms) so that two threads collide trying to create temp files at the same time.  So the scheme needs to be able to recover gracefully from collisions. Something like adding a sequence number on the millis value until you can successfully create an OutputStream on the named file.

Jim
Thanks

I have lots of options to consider.
Well, don't think it's that difficult. If you want the files to remain after the lifetime of your app, that really rules out createTempFile. Whatever method you use to generate, unless you need great speed, you can always check to see if any new file exists so really there's not much of a problem
Thanks

If I create the temp file using createTempFile and then, write to this temp file similar to below. I thought this would create a permant file, and with a unquie filename?

    File path = new File("/files/userfolder");
    File newFile = File.createTempFile(tmp, extension, path);

    FileOutputStream out = new FileOutputStream(newFile);
    byte[] bytes = new byte[(int)currentFile.length()];
    out.write(bytes, 0, bytes.length);
    out.flush();
    out.close();
   
Just *forget* createTempFile - it's not what you need
Thanks,

CEHJ, do you mean when the createTempFile method creates a file in the folder. And we write the orginal file content as below to that file. This created file is still only temporary and will be removed at somepoint automatically?

    File path = new File("/files/userfolder");
    File newFile = File.createTempFile(tmp, extension, path);

    FileOutputStream out = new FileOutputStream(newFile);
    byte[] bytes = new byte[(int)currentFile.length()];
    out.write(bytes, 0, bytes.length);
    out.flush();
    out.close();
>>This created file is still only temporary and will be removed at somepoint automatically?

It really depends on whether you use the 2-arg or 3-arg version. The latter allows you to specify the directory, but you still won't have full control over the name if that's what you want
The file won't be removed automatically unless you also do:
    newFile.deleteOnExit();

Then the File represented by newFile will be removed when the JVM terminates. Probably not what you want if this is running in an application server as you don't know when the server will be restarted or how long it might run before that happens.
Thanks

Orginally I planned to name the files uploaded and saved on the server as tmp1, tmp2, tmp3.... ect.

This was not important, I just wanted the filenames to be unique. I think there seems two ways of creating the unquie filenames.

Using the createTempFile method and writing the orginal file content to the file create by this method. And not using the deleteonExit().

Or using the filename tmp and adding the System.currentTimeMillis to this filename and checking to be sure the tmp+System.currentTimeMillis does not exist in the users folder. Before we write the file.

I just thought the use of createTempFile was the simplist.
Yes. If you don't need sequencing use the 3-arg createTempFile
The createTempFile 3-arg, I guess was orginally intended to create temporary files. Perhaps using in the way I am suggesting goes against its purpose. Though this is only a small issue.

I just wondered using the System.currentTimeMillis, how many numbers would this add to the end of tmp?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks everyone for your guidance.
:-)