Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create temp path without creating the file

Tags:

java

file

path

temp

Is there any way of creating a temp file path without creating the file ?

Basically I need an equivalent for the method Files.createTempFile(...) without creating the file.

I can use this workaround for my purpose :

Path pathFile = null;
pathFile = Files.createTempFile("tempFile","");
pathFile.toFile().delete();

But I would like to use a much cleaner way.

Does that exist ? I don't find it.

like image 540
alexrn Avatar asked Nov 16 '25 13:11

alexrn


1 Answers

The code that powers createTempFile is the class java.nio.file.TempFileHelper, which is private, and an implementation detail, so you can't rely on it. However, it's a fine source file to read to figure out how this works.

This code does a few things:

  1. "Fix up" the permissions structure if on a posix file system.
  2. call generatePath to generate a random name.
  3. Try to make the file.
  4. If #3 failed for any reason, loop back to 2 until it works out.

And thus we get to the fundamental problem of what you want: The primary things that TempFileHelper do cannot be done if it conveys just a path to you.

Specifically:

  1. Ensure the permissions are set up correctly. In particular, this file must not be readable or writeable by anything else as much as possible. This cannot be conveyed in a Path object.
  2. Ensure that the file, if created (because what else is the point of generating a temporary file name?), is in fact 'appropriate': It is actually created, just now, for you, with the right permissions. You can't convey that in a Path object either.

The actual code that generates the name is trivial. It makes no effort to check if that filename is 'free' (that's what the loop structure that re-tries if creating the file does not work is for).

This is it:

    private static Path generatePath(String prefix, String suffix, Path dir) {
        long n = random.nextLong();
        String s = prefix + Long.toUnsignedString(n) + suffix;
        Path name = dir.getFileSystem().getPath(s);
        // the generated name should be a simple file name
        if (name.getParent() != null)
            throw new IllegalArgumentException("Invalid prefix or suffix");
        return dir.resolve(name);
    }

and furthermore, if you don't explicitly specify which dir you want to create the file in, the code of TempFileHelper will use the value of tmpdir:

    private static final Path tmpdir =
        Path.of(GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));

I guess your basic question is 'can I call that on its own'. To fully answer your question:

  1. I think you're underestimating what a temp file means. Please doublecheck your assumptions. For example, hypothetically, if you had an API to ask for a 'temp file path', you have almost no guarantees about it. You wouldn't know if, later, when you use this path to e.g. create a file, if that will work (is it 'free', as in, does the file not currently exist, is the directory there? Do you have write access?), nor if the security is set up correctly (set as many flags as possible to ensure as few entities on the system have access to it). Mostly, then, it sounds like this task, if properly festooned with the assumptions you have to make about it, is useless, so why do you want this?

  2. The code that powers the 'generate random name' part is near trivial. Use sysproperty java.io.tmpdir and the above code. This is only a tiny part of all the stuff TempFileHelper does.

  3. The generate random name part is not public API and is unlikely to ever be, as that would be a very badly designed API: It would insinuate that asking for a random file name is useful for the purposes of making tmp files. But it isn't, so, that'd be bad API.

  4. Your workaround has mostly the same problems: That merely means that file was 'free', properly permissioned, and writable at the time you generated the Path object, but it cannot carry those promises forward.

The better solution?

Why not make a function or whatnot that 'makes a file'?

@FunctionalInterface
function OutputMaker {
    public OutputStream make() throws IOException;
}

// and an implementation of this:

OutputMaker tempFileMaker = () -> {
    Path p = Files.createTempFile("tempFile", "");
    return Files.newOutputStream(p);
};

That interface may have to look different; your question does not explain what you want to 'do' with a temporary path.

like image 81
rzwitserloot Avatar answered Nov 18 '25 05:11

rzwitserloot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!