Secure temporary file: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Go}}: Explicitly close the temporary file; also actually use the file a little bit (grr.. damn recaptcha crap))
m (→‎{{header|Wren}}: Minor tidy)
 
(45 intermediate revisions by 26 users not shown)
Line 1: Line 1:
{{Task|Programming environment operations}}
{{Task|Programming environment operations}}Create a temporary file, '''securely and exclusively''' (opening it such that there are no possible [[race condition|race conditions]]). It's fine assuming local filesystem semantics (NFS or other networking filesystems can have signficantly more complicated semantics for satisfying the "no race conditions" criteria). The function should automatically resolve name collisions and should only fail in cases where permission is denied, the filesystem is read-only or full, or similar conditions exist (returning an error or raising an exception as appropriate to the language/environment).

;Task:
Create a temporary file, '''securely and exclusively''' (opening it such that there are no possible [[race condition|race conditions]]).

It's fine assuming local filesystem semantics (NFS or other networking filesystems can have signficantly more complicated semantics for satisfying the "no race conditions" criteria).

The function should automatically resolve name collisions and should only fail in cases where permission is denied, the filesystem is read-only or full, or similar conditions exist (returning an error or raising an exception as appropriate to the language/environment).
<br><br>


=={{header|Ada}}==
=={{header|Ada}}==
Line 6: Line 14:
This example creates a temporary file, writes to the file, then reads from the file.
This example creates a temporary file, writes to the file, then reads from the file.


<lang ada>with Ada.Text_Io; use Ada.Text_Io;
<syntaxhighlight lang="ada">with Ada.Text_Io; use Ada.Text_Io;


procedure Temp_File is
procedure Temp_File is
Line 19: Line 27:
Get_Line(File => Temp, Item => Contents, Last => Length);
Get_Line(File => Temp, Item => Contents, Last => Length);
Put_Line(Contents(1..Length));
Put_Line(Contents(1..Length));
end Temp_File;</lang>
end Temp_File;</syntaxhighlight>


=={{header|BBC BASIC}}==
=={{header|BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
The file is automatically deleted when closed.
The file is automatically deleted when closed.
<lang bbcbasic> file% = FNopentempfile
<syntaxhighlight lang="bbcbasic"> file% = FNopentempfile
IF file% = 0 ERROR 100, "Failed to open temp file"
IF file% = 0 ERROR 100, "Failed to open temp file"
PRINT #file%, "Hello world!"
PRINT #file%, "Hello world!"
Line 50: Line 59:
IF hfile% = INVALID_HANDLE_VALUE THEN = 0
IF hfile% = INVALID_HANDLE_VALUE THEN = 0
@hfile%(chan%) = hfile%
@hfile%(chan%) = hfile%
= chan%</lang>
= chan%</syntaxhighlight>
'''Output:'''
'''Output:'''
<pre>
<pre>
Hello world!
Hello world!
</pre>
</pre>

==={{header|FreeBASIC}}===
{{trans|BBC BASIC}}
The file is deleted when closed.
<syntaxhighlight lang="vb">Dim As Long f
Dim As String message

f = Freefile
Open "temp.txt" For Output As #f
If Err > 0 Then Print "Failed to open temp"; f : End
Print #f, "Hello world!"
Close #f

Open "temp.txt" For Input As #f
Line Input #f, message
Close #f
Print message

Shell "del temp.txt"

Sleep</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
<lang c>#include <stdlib.h>
<syntaxhighlight lang="c">#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>


Line 70: Line 100:
time you open it. */
time you open it. */
return 0;
return 0;
}</lang>
}</syntaxhighlight>


The following {{works with|POSIX}}
The following {{works with|POSIX}}
<lang c>#include <stdlib.h>
<syntaxhighlight lang="c">#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>


Line 84: Line 114:
close(fd);
close(fd);
return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==


<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.IO;
using System.IO;


Console.WriteLine(Path.GetTempFileName());</lang>
Console.WriteLine(Path.GetTempFileName());</syntaxhighlight>=={{header|C sharp|C#}}==

=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cstdio>

int main() {
// Creates and opens a temporary file with a unique auto-generated filename.
// If the program closes the file, the file is automatically deleted.
// The file is also automatically deleted if the program exits normally.
std::FILE* temp_file_pointer = std::tmpfile();

// Using functions which take a file pointer as an argument
std::fputs("Hello world", temp_file_pointer);
std::rewind(temp_file_pointer);
char buffer[12];
std::fgets(buffer, sizeof buffer, temp_file_pointer);
printf(buffer);
}
</syntaxhighlight>
{{ out }}
<pre>
Hello world
</pre>


=={{header|Clojure}}==
=={{header|Clojure}}==
It is good practice to explicitly delete temp files immediately once they've been used.
It is good practice to explicitly delete temp files immediately once they've been used.
<lang clojure>(let [temp-file (java.io.File/createTempFile "pre" ".suff")]
<syntaxhighlight lang="clojure">(let [temp-file (java.io.File/createTempFile "pre" ".suff")]
; insert logic here that would use temp-file
; insert logic here that would use temp-file
(.delete temp-file))</lang>
(.delete temp-file))</syntaxhighlight>


=={{header|D}}==
=={{header|D}}==
{{works with|Tango}}
{{works with|Tango}}
<lang d>module tempfile ;
<syntaxhighlight lang="d">module tempfile ;
import tango.io.TempFile, tango.io.Stdout ;
import tango.io.TempFile, tango.io.Stdout ;


Line 115: Line 168:


// both can only be accessed by the current user (the program?).
// both can only be accessed by the current user (the program?).
}</lang>
}</syntaxhighlight>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.IOUtils}}
<syntaxhighlight lang="delphi">
program Secure_temporary_file;

{$APPTYPE CONSOLE}

uses
System.SysUtils,
System.IOUtils;

var
FileName, buf: string;

begin
FileName := TPath.GetTempFileName;
with TFile.Open(FileName, TFileMode.fmCreate, TFileAccess.faReadWrite,
Tfileshare.fsNone) do
begin
buf := 'This is a exclusive temp file';
Write(buf[1], buf.Length * sizeof(char));
Free;
end;

writeln(FileName);
Readln;
end.</syntaxhighlight>


=={{header|Emacs Lisp}}==
=={{header|Emacs Lisp}}==
<code>make-temp-file</code> creates a new empty temporary file, with perms "0700" so read-write to the current user only.
<code>make-temp-file</code> creates a new empty temporary file, with perms "0700" so read-write to the current user only.


<lang Lisp>(make-temp-file "prefix")
<syntaxhighlight lang="lisp">(make-temp-file "prefix")
;; => "/tmp/prefix25452LPe"</syntaxhighlight>
=>

"/tmp/prefix25452LPe"</lang>
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
printfn $"%s{System.IO.Path.GetTempFileName()}"
</syntaxhighlight>
{{out}}
<pre>
/tmp/tmpEuSgiY.tmp
</pre>
For the cynical who may not believe the file has been created
</pre>
nigel@nigel:/tmp$ ls *.tmp
tmpEuSgiY.tmp
</pre>


=={{header|Fortran}}==
Supposing F is an integer variable, whose value might be 10. This is the I/O unit number, and would be used in READ(F,''etc.'' and WRITE(F,''etc.'' statements. <syntaxhighlight lang="fortran"> OPEN (F,STATUS = 'SCRATCH') !Temporary disc storage.</syntaxhighlight>
Other attributes might be specified depending on the intended usage, but note that no file name is given. When the file is closed, its storage vanishes back to the file system.


Following the OPEN statement with <code>INQUIRE (F,NAME = FNAME); WRITE (6,*) FNAME</code> yields <code> C:\DOCUME~1\Nicky\LOCALS~1\Temp\FOR57.tmp</code> which is the DOS style short (8.3) file name for <code>C:\Documents and Settings\Nicky\Local Settings\Temp\FOR57.tmp</code> and the example's numerical value of 57 will be different on another run. Thus, the file could be interfered with, except that a file opened with WRITE access is exclusive-use, and there is no point in opening a SCRATCH file with READONLY (to allow sharing) because it cannot be a pre-existing disc file. However, the actual behaviour of a particular file system and compiler may or may not support such refinements as shared access as implied by non-standard keywords as READONLY, etc.
<code>make-temp-file</code> is available in GNU Emacs 21 up, but not XEmacs 21.4. The Gnus included with XEmacs 21.4 has an <code>mm-make-temp-file</code> in its <code>mm-util.el</code>, or the [[APEL]] library can supply a <code>make-temp-file</code> (and for Emacs 20 too).


=={{header|Go}}==
=={{header|Go}}==
Use <code>[https://golang.org/pkg/io/ioutil/#TempFile ioutil.TempFile]</code>
Use <code>[https://golang.org/pkg/io/ioutil/#TempFile ioutil.TempFile]</code>
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 159: Line 258:
// The defer statements above will close and remove the
// The defer statements above will close and remove the
// temporary file here (or on any return of this function).
// temporary file here (or on any return of this function).
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 166: Line 265:


=={{header|Groovy}}==
=={{header|Groovy}}==
{{incomplete|Groovy|JVM Windows related bug workaround JDK-4715154}}Follows technique of Java example<lang groovy>def file = File.createTempFile( "xxx", ".txt" )
<syntaxhighlight lang="groovy">def file = File.createTempFile( "xxx", ".txt" )

file.deleteOnExit()
// There is no requirement in the instructions to delete the file.
println file</lang>
//file.deleteOnExit()

println file</syntaxhighlight>


Output:
Output:
Line 174: Line 276:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>import System.IO
<syntaxhighlight lang="haskell">import System.IO


main = do (pathOfTempFile, h) <- openTempFile "." "prefix.suffix" -- first argument is path to directory where you want to put it
main = do (pathOfTempFile, h) <- openTempFile "." "prefix.suffix" -- first argument is path to directory where you want to put it
-- do stuff with it here; "h" is the Handle to the opened file
-- do stuff with it here; "h" is the Handle to the opened file
return ()</lang>
return ()</syntaxhighlight>


=={{header|HicEst}}==
=={{header|HicEst}}==
<lang HicEst>! The "scratch" option opens a file exclusively for the current process.
<syntaxhighlight lang="hicest">! The "scratch" option opens a file exclusively for the current process.
! A scratch file is automatically deleted upon process termination.
! A scratch file is automatically deleted upon process termination.


Line 192: Line 294:
OPEN( FIle='DenyForOthers', DenyREAdWRIte, IOStat=ErrNr)
OPEN( FIle='DenyForOthers', DenyREAdWRIte, IOStat=ErrNr)
WRITE(FIle='DenyForOthers') "something"
WRITE(FIle='DenyForOthers') "something"
WRITE(FIle='DenyForOthers', DELETE=1)</lang>
WRITE(FIle='DenyForOthers', DELETE=1)</syntaxhighlight>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
Line 198: Line 300:
A posix-based solution that works in both languages:
A posix-based solution that works in both languages:


<lang unicon>procedure main()
<syntaxhighlight lang="unicon">procedure main()
write("Creating: ",fName := !open("mktemp","rp"))
write("Creating: ",fName := !open("mktemp","rp"))
write(f := open(fName,"w"),"Hello, world")
write(f := open(fName,"w"),"Hello, world")
close(f)
close(f)
end</lang>
end</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
{{Incomplete|Java|JVM Windows related bug workaround JDK-4715154}}<lang java>import java.io.File;


<syntaxhighlight lang="java">import java.io.File;
try {
import java.io.IOException;
// Create temp file
File filename = File.createTempFile("prefix", ".suffix");


public class CreateTempFile {
// Delete temp file when program exits
public static void main(String[] args) {
filename.deleteOnExit();
try {
//create a temp file
File temp = File.createTempFile("temp-file-name", ".tmp");
System.out.println("Temp file : " + temp.getAbsolutePath());
}
catch(IOException e) {
e.printStackTrace();
}
}
}</syntaxhighlight>


Alternative example
System.out.println(filename);
<syntaxhighlight lang="java">
import java.io.BufferedWriter;
import java.nio.file.Files;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public final class SecureTemporaryFile {

public static void main(String[] args) throws IOException {
// Create a temporary file in the directory D:\.
// We should use java.nio.file.Files instead of the old java.io.File, as it is more secure.
// If the file cannot be created, it will throw an exception.
Path temporaryFilePath = Files.createTempFile(Path.of("D:/"), "example", ".tmp");

// For uniqueness, the Java API will insert a random number between the given prefix
// and the file extension.
System.out.println("Temporary file created: " + temporaryFilePath);

// Opening it with the following option will cause the file to be deleted when it is closed.
BufferedWriter tempFileWriter = Files.newBufferedWriter(
temporaryFilePath, StandardOpenOption.DELETE_ON_CLOSE);
// ... write to file, read it back in, close it...
}

}
</syntaxhighlight>
{{ out }}
<pre>
Temporary file created: D:\example12312088502442779987.tmp
</pre>

=={{header|Julia}}==
{{works with|Linux}} On Unix systems, Julia calls <code>mkstemp</code> to securely open a temporary file. This is likely multi-thread safe, check your system documentation for verification. This code should also work on Windows, but I've not verified that.
<syntaxhighlight lang="julia">
msg = "Rosetta Code, Secure temporary file, implemented with Julia."

(fname, tio) = mktemp()
println(fname, " created as a temporary file.")
println(tio, msg)
close(tio)
println("\"", msg, "\" written to ", fname)
</syntaxhighlight>
Files written to <code>\tmp</code> persist for the login session, and are thus truly temporary. If the environment variable <code>TMPDIR</code> is set, the temporary file is created in this directory. In this case, the file may not be properly temporary.
<syntaxhighlight lang="julia">
ENV["TMPDIR"] = pwd()
(fname, tio) = mktemp()
println(fname, " created as a \"temporary\" file.")
println(tio, msg)
close(tio)
println("\"", msg, "\" written to ", fname)
</syntaxhighlight>

{{out}}
<pre>
/tmp/tmphe0qlu created as a temporary file.
"Rosetta Code, Secure temporary file, implemented with Julia." written to /tmp/tmphe0qlu
/home/mike/rosetta/julia/tmpVNGK8D created as a "temporary" file.
"Rosetta Code, Secure temporary file, implemented with Julia." written to /home/joeb/rosetta/julia/tmpVNGK8D
$ cat /tmp/tmphe0qlu
Rosetta Code, Secure temporary file, implemented with Julia.
$ ls -l /tmp/tmphe0qlu
-rw------- 1 joeb joeb 61 Apr 13 13:18 /tmp/tmphe0qlu
$ cat tmpVNGK8D
Rosetta Code, Secure temporary file, implemented with Julia.
$ ls -l tmpVNGK8D
-rw------- 1 joeb jeob 61 Apr 13 13:18 tmpVNGK8D
</pre>

=={{header|Kotlin}}==
<syntaxhighlight lang="kotlin">import kotlin.io.path.createTempFile
import kotlin.io.path.deleteExisting

fun main() {
val tempFilePath = createTempFile("example", ".tmp")
println("Temporary file created: $tempFilePath")
tempFilePath.deleteExisting()
}</syntaxhighlight>
Sample output:
{{out}}
<pre>
Temporary file created: /tmp/example14437465325231438926.tmp
</pre>


} catch (IOException e) {
}</lang>
=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>fp = io.tmpfile()
<syntaxhighlight lang="lua">fp = io.tmpfile()


-- do some file operations
-- do some file operations


fp:close()</lang>
fp:close()</syntaxhighlight>

=={{header|M2000 Interpreter}}==
tmp files automatic deleted when Environment end (per running environment)

<syntaxhighlight lang="m2000 interpreter">
Module Checkit {
\\ we get a tempname$ choosed from Windows
a$=tempname$
Try ok {
\\ we can use wide to export in utf-16le
\\ without wide we export as Ansi (set Local to desired language)
Rem Locale 1033 ' when no use of wide
Open a$ for wide output exclusive as #f
wait 10
\\ Notepad can't open, because we open it for exclusive use
Win "Notepad", a$
Print #f, "something"
Print "Press a key";Key$
Close #f
}
If error or not ok then Print Error$
Win "Notepad", a$
}
Checkit

</syntaxhighlight>

=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">tmp = OpenWrite[]
Close[tmp]</syntaxhighlight>

=={{header|Nanoquery}}==
<syntaxhighlight lang="nanoquery">import Nanoquery.IO

def guaranteedTempFile()
// create a file object to generate temp file names
$namegen = new(File)

// generate a temp filename
$tempname = $namegen.tempFileName()
// file names are generated with uuids so they shouldn't repeat
// in the case that they do, generate new ones until the generated
// filename is unique
$tempfile = new(File, $tempname)
while ($tempfile.exists())
$tempname = $namegen.tempFileName()
$tempfile = new(File, $tempname)
end

// create the file and lock it from writing
$tempfile.create()
lock $tempfile.fullPath()


// return the file reference
=={{header|Mathematica}}==
return $tempfile
<lang Mathematica>tmp = OpenWrite[]
end</syntaxhighlight>
Close[tmp]</lang>


=={{header|NetRexx}}==
=={{header|NetRexx}}==
{{incomplete|NetRexx|JVM Windows related bug workaround JDK-4715154}}<lang NetRexx>/* NetRexx */
{{incomplete|NetRexx|JVM Windows related bug workaround JDK-4715154}}<syntaxhighlight lang="netrexx">/* NetRexx */
options replace format comments java crossref symbols binary
options replace format comments java crossref symbols binary


Line 261: Line 505:
end
end
return
return
</syntaxhighlight>
</lang>

=={{header|Nim}}==
{{Works with|Nim|1.6.0}}
<syntaxhighlight lang="nim">import std/[os, tempfiles]

let (file, path) = createTempFile(prefix = "", suffix = "")
echo path, " created."
file.writeLine("This is a secure temporary file.")
file.close()
for line in path.lines:
echo line
removeFile(path)</syntaxhighlight>
{{out}}
<pre>/tmp/th7lDdkH created.
This is a secure temporary file.</pre>


=={{header|OCaml}}==
=={{header|OCaml}}==
From the module Filename, one can use the functions [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Filename.html#VALtemp_file temp_file] or [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Filename.html#VALopen_temp_file open_temp_file]
From the module Filename, one can use the functions [https://ocaml.org/api/Filename.html#VALtemp_file temp_file] or [https://ocaml.org/api/Filename.html#VALopen_temp_file open_temp_file]
<lang ocaml># Filename.temp_file "prefix." ".suffix" ;;
<syntaxhighlight lang="ocaml"># Filename.temp_file "prefix." ".suffix" ;;
- : string = "/home/blue_prawn/tmp/prefix.301f82.suffix"</lang>
- : string = "/home/blue_prawn/tmp/prefix.301f82.suffix"</syntaxhighlight>


=={{header|Octave}}==
=={{header|Octave}}==


Octave has several related functions
Octave has several related functions
<lang Matlab> [FID, MSG] = tmpfile(); % Return the file ID corresponding to a new temporary
<syntaxhighlight lang="matlab"> [FID, MSG] = tmpfile(); % Return the file ID corresponding to a new temporary
filename = tmpnam (...); % generates temporary file name, but does not open file
filename = tmpnam (...); % generates temporary file name, but does not open file
[FID, NAME, MSG] = mkstemp (TEMPLATE, DELETE); % Return the file ID corresponding to a new temporary file with a unique name created from TEMPLATE.</lang>
[FID, NAME, MSG] = mkstemp (TEMPLATE, DELETE); % Return the file ID corresponding to a new temporary file with a unique name created from TEMPLATE.</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
{{works with|Free_Pascal}}
{{works with|Free_Pascal}}
{{libheader|SysUtils}}
{{libheader|SysUtils}}
<lang pascal>Program TempFileDemo;
<syntaxhighlight lang="pascal">Program TempFileDemo;


uses
uses
Line 291: Line 550:
writeln (tempFile, 5);
writeln (tempFile, 5);
close (tempFile);
close (tempFile);
end.</lang>
end.</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
function interface:
function interface:
<lang perl>use File::Temp qw(tempfile);
<syntaxhighlight lang="perl">use File::Temp qw(tempfile);
$fh = tempfile();
$fh = tempfile();
($fh2, $filename) = tempfile(); # this file stays around by default
($fh2, $filename) = tempfile(); # this file stays around by default
print "$filename\n";
print "$filename\n";
close $fh;
close $fh;
close $fh2;</lang>
close $fh2;</syntaxhighlight>


object-oriented interface:
object-oriented interface:
<lang perl>use File::Temp;
<syntaxhighlight lang="perl">use File::Temp;
$fh = new File::Temp;
$fh = new File::Temp;
print $fh->filename, "\n";
print $fh->filename, "\n";
close $fh;</lang>
close $fh;</syntaxhighlight>

=={{header|Phix}}==
The temp_file() function (see builtins/pfile.e) can be used for this:
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (file i/o)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">temp_file</span><span style="color: #0000FF;">())</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">temp_file</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"myapp/tmp"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"data"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"log"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wb"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">delete_file</span><span style="color: #0000FF;">(</span><span style="color: #000000;">name</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
`C:\Users\Pete\AppData\Local\Temp\419750.tmp`
{3, `C:\Program Files (x86)\Phix\myapp\tmp\data408865.log`}
</pre>
If you don't provide an open mode (one of "w", "wb", "a", or "ab") then there is a 1-in-a-million
chance someone else will beat you to the punch; if you do provide one, it will open/loop for you.


=={{header|PHP}}==
=={{header|PHP}}==
<lang php>$fh = tmpfile();
<syntaxhighlight lang="php">$fh = tmpfile();
// do stuff with $fh
// do stuff with $fh
fclose($fh);
fclose($fh);
Line 317: Line 594:
$filename = tempnam('/tmp', 'prefix');
$filename = tempnam('/tmp', 'prefix');
echo "$filename\n";
echo "$filename\n";
// open $filename and do stuff with it</lang>
// open $filename and do stuff with it</syntaxhighlight>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Line 326: Line 603:
they are (e.g. because such a file name is passed to a child process), explicit
they are (e.g. because such a file name is passed to a child process), explicit
locks with the 'ctl' functions are possible.
locks with the 'ctl' functions are possible.
<lang PicoLisp>: (out (tmp "foo") (println 123)) # Write tempfile
<syntaxhighlight lang="picolisp">: (out (tmp "foo") (println 123)) # Write tempfile
-> 123
-> 123


Line 334: Line 611:
: (let F (tmp "foo")
: (let F (tmp "foo")
(ctl F # Get exclusive lock
(ctl F # Get exclusive lock
(in F
(let N (in F (read)) # Atomic increment
(out F (println (inc N))) ) ) )
(let N (read) # Atomic increment
(out F (println (inc N))) ) ) ) )
-> 124</lang>
-> 124</syntaxhighlight>

=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
$tempFile = [System.IO.Path]::GetTempFileName()
Set-Content -Path $tempFile -Value "FileName = $tempFile"
Get-Content -Path $tempFile
Remove-Item -Path $tempFile
</syntaxhighlight>
{{Out}}
<pre>
FileName = C:\Users\Owner\AppData\Local\Temp\tmpB68.tmp
</pre>


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>Procedure.s TempFile()
<syntaxhighlight lang="purebasic">Procedure.s TempFile()
Protected a, Result$
Protected a, Result$


Line 363: Line 653:
CloseFile(File)
CloseFile(File)
EndIf
EndIf
EndIf</lang>
EndIf</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
Line 370: Line 660:




<lang python>>>> import tempfile
<syntaxhighlight lang="python">>>> import tempfile
>>> invisible = tempfile.TemporaryFile()
>>> invisible = tempfile.TemporaryFile()
>>> invisible.name
>>> invisible.name
Line 378: Line 668:
'/tmp/tmpZNfc_s'
'/tmp/tmpZNfc_s'
>>> visible.close()
>>> visible.close()
>>> invisible.close()</lang>
>>> invisible.close()</syntaxhighlight>




Line 384: Line 674:




<lang python>fd, path = tempfile.mkstemp()
<syntaxhighlight lang="python">fd, path = tempfile.mkstemp()
try:
try:
# use the path or the file descriptor
# use the path or the file descriptor
finally:
finally:
os.close(fd)</lang>
os.close(fd)</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==


<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket
(make-temporary-file)
(make-temporary-file)
</syntaxhighlight>
</lang>

=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2017.09}}
This is something best done with a module which is heavily tested, tries to account for all corner cases and automatically cleans up after itself.

Almost verbatim from the synopsis:
<syntaxhighlight lang="raku" line>use File::Temp;

# Generate a temp file in a temp dir
my ($filename0,$filehandle0) = tempfile;

# specify a template for the filename
# * are replaced with random characters
my ($filename1,$filehandle1) = tempfile("******");

# Automatically unlink files at DESTROY (this is the default)
my ($filename2,$filehandle2) = tempfile("******", :unlink);

# Specify the directory where the tempfile will be created
my ($filename3,$filehandle3) = tempfile(:tempdir("/path/to/my/dir"));

# don't unlink this one
my ($filename4,$filehandle4) = tempfile(:tempdir('.'), :!unlink);

# specify a prefix, a suffix, or both for the filename
my ($filename5,$filehandle5) = tempfile(:prefix('foo'), :suffix(".txt"));</syntaxhighlight>

=={{header|REXX}}==
REXX uses the underlying OS to create and delete the file.
<syntaxhighlight lang="rexx">/*REXX pgm secures (a temporary file), writes to it, displays the file, then deletes it.*/
parse arg tFID # . /*obtain optional argument from the CL.*/
if tFID=='' | tFID=="," then tFID= 'TEMP.FILE' /*Not specified? Then use the default.*/
if #=='' | #=="," then #= 6 /* " " " " " " */
call lineout tFID /*insure file is closed. */
rc= 0
say '··· creating file: ' tFID
call lineout tFID,,1 /*insure file is open and at record 1. */
if rc\==0 then call ser rc 'creating file' tFID /*issue error if can't open the file. */
say '··· writing file: ' tFID

do j=1 for # /*write a half-dozen records to file. */
call lineout tFID, 'line' j /*write a record to the file. */
if rc\==0 then call ser rc 'writing file' tFID /*Have an error? Issue err msg.*/
end /*j*/

call lineout tFID /*close the file. */
say '··· reading/display file: ' tFID

do j=1 while lines(tFID)>0 /*read the entire file and display it. */
x= linein(tFID) /*read a record from the file. */
if rc\==0 then call ser rc 'reading file' tFID /*Have an error? Issue err msg.*/
say 'line ' j " of file" tFID":" x /*display a record to the term. */
end /*j*/

call lineout tFID /*close the file. */
say '··· erasing file: ' tFID
'ERASE' tFID /*erase the file. */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
ser: say; say '***error***' arg(1); say; exit 13 /*issue an error message to the term. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
··· creating file: TEMP.FILE
··· writing file: TEMP.FILE
··· reading/display file: TEMP.FILE
line 1 of file TEMP.FILE: line 1
line 2 of file TEMP.FILE: line 2
line 3 of file TEMP.FILE: line 3
line 4 of file TEMP.FILE: line 4
line 5 of file TEMP.FILE: line 5
line 6 of file TEMP.FILE: line 6
··· erasing file: TEMP.FILE
</pre>


=={{header|Ruby}}==
=={{header|Ruby}}==
<lang ruby>irb(main):001:0> require 'tempfile'
<syntaxhighlight lang="ruby">require 'tempfile'

=> true
irb(main):002:0> f = Tempfile.new('foo')
f = Tempfile.new('foo')
=> #<File:/tmp/foo20081226-307-10p746n-0>
f.path # => "/tmp/foo20081226-307-10p746n-0"
f.close
irb(main):003:0> f.path
f.unlink # => #<Tempfile: (closed)></syntaxhighlight>
=> "/tmp/foo20081226-307-10p746n-0"

irb(main):004:0> f.close
=={{header|Rust}}==
=> nil</lang>
<syntaxhighlight lang="rust">// 202100322 Rust programming solution

use tempfile::tempfile;

fn main() {

let fh = tempfile();

println!("{:?}", fh);
}</syntaxhighlight>
{{out}}
<pre>
Ok(File { fd: 3, path: "/tmp/#37224506 (deleted)", read: true, write: true })
</pre>

=={{header|Scala}}==
=={{header|Scala}}==
<lang scala>import java.io.{File, FileWriter, IOException}
<syntaxhighlight lang="scala">import java.io.{File, FileWriter, IOException}


def writeStringToFile(file: File, data: String, appending: Boolean = false) =
def writeStringToFile(file: File, data: String, appending: Boolean = false) =
Line 424: Line 803:
} catch {
} catch {
case e: IOException => println(s"Running Example failed: ${e.getMessage}")
case e: IOException => println(s"Running Example failed: ${e.getMessage}")
}</lang>
}</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>var tmpfile = require('File::Temp');
<syntaxhighlight lang="ruby">var tmpfile = require('File::Temp');
var fh = tmpfile.new(UNLINK => 0);
var fh = tmpfile.new(UNLINK => 0);
say fh.filename;
say fh.filename;
fh.print("Hello, World!\n");
fh.print("Hello, World!\n");
fh.close;</lang>
fh.close;</syntaxhighlight>

=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "tmpfile" );
pragma annotate( description, "Create a temporary file, securely and exclusively" );
pragma annotate( description, "(opening it such that there are no possible race" );
pragma annotate( description, "conditions). It's fine assuming local filesystem" );
pragma annotate( description, "semantics (NFS or other networking filesystems can" );
pragma annotate( description, "have signficantly more complicated semantics for" );
pragma annotate( description, "satisfying the 'no race conditions' criteria). The" );
pragma annotate( description, "function should automatically resolve name collisions" );
pragma annotate( description, "and should only fail in cases where permission is" );
pragma annotate( description, "denied, the filesystem is read-only or full, or similar" );
pragma annotate( description, "conditions exist (returning an error or raising an" );
pragma annotate( description, "exception as appropriate to the language/environment)." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Secure_temporary_file" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );

pragma restriction( no_external_commands );

procedure tmpfile is
temp : file_type;
contents : string;
begin
? "Creating a temporary file";
create( temp );
put_line( temp, "Hello World");

? "Reading a temporary file";
reset( temp, in_file);
contents := get_line( temp );
put_line( "File contains: " & contents );

? "Discarding a temporary file";
close( temp );
end tmpfile;</syntaxhighlight>


=={{header|Standard ML}}==
=={{header|Standard ML}}==
<lang sml>val filename = OS.FileSys.tmpName ();</lang>
<syntaxhighlight lang="sml">val filename = OS.FileSys.tmpName ();</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
{{works with|Tcl|8.6}}
Will store the name of the file in the variable <code>filenameVar</code> and an open read-write channel on the file in the variable <code>chan</code>.
Will store the name of the file in the variable <code>filenameVar</code> and an open read-write channel on the file in the variable <code>chan</code>.
<lang Tcl>set chan [file tempfile filenameVar]</lang>
<syntaxhighlight lang="tcl">set chan [file tempfile filenameVar]</syntaxhighlight>
Note that because we're asking for the filename in the script, Tcl does not automatically clean the file. (There are cases where auto-cleaning would be really unwanted.) If we hadn't asked for it, the file would be automatically deleted (at a time that depends on platform constraints).
Note that because we're asking for the filename in the script, Tcl does not automatically clean the file. (There are cases where auto-cleaning would be really unwanted.) If we hadn't asked for it, the file would be automatically deleted (at a time that depends on platform constraints).

=={{header|TUSCRIPT}}==
=={{header|TUSCRIPT}}==
<lang tuscript>
<syntaxhighlight lang="tuscript">
$$ MODE TUSCRIPT
$$ MODE TUSCRIPT
tmpfile="test.txt"
tmpfile="test.txt"
Line 449: Line 867:
FILE $tmpfile = text
FILE $tmpfile = text
- tmpfile "test.txt" can only be accessed by one user an will be deleted upon programm termination
- tmpfile "test.txt" can only be accessed by one user an will be deleted upon programm termination
</syntaxhighlight>
</lang>


=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==
Line 458: Line 876:
thereunder.
thereunder.


<lang bash>RESTOREUMASK=$(umask)
<syntaxhighlight lang="bash">RESTOREUMASK=$(umask)
TRY=0
TRY=0
while :; do
while :; do
Line 470: Line 888:
cd "$MYTMP" || {
cd "$MYTMP" || {
echo "Temporary directory failure on $MYTMP" >&2
echo "Temporary directory failure on $MYTMP" >&2
exit 1; }</lang>
exit 1; }</syntaxhighlight>


Note that the shell special variable $$ (the PID of the currently ''exec()''-ed shell) is unique at any given
Note that the shell special variable $$ (the PID of the currently ''exec()''-ed shell) is unique at any given
Line 477: Line 895:
This code will loop, picking new names and resetting the ''trap'' (clean-up command) until it succeeds in making
This code will loop, picking new names and resetting the ''trap'' (clean-up command) until it succeeds in making
a directory. (Simple changes to the code could limit the number of attempts or implement a timeout).
a directory. (Simple changes to the code could limit the number of attempts or implement a timeout).

=={{header|Wren}}==
{{libheader|Wren-ioutil}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./ioutil" for File, FileUtil
import "./fmt" for Fmt

var rand = Random.new()

var createTempFile = Fn.new { |lines|
var tmp
while (true) {
// create a name which includes a random 6 digit number
tmp = "/tmp/temp%(Fmt.swrite("$06d", rand.int(1e6))).tmp"
if (!File.exists(tmp)) break
}
FileUtil.writeLines(tmp, lines)
return tmp
}

var lines = ["one", "two", "three"]
var tmp = createTempFile.call(lines)
System.print("Temporary file path: %(tmp)")
System.print("Original contents of temporary file:")
System.print(File.read(tmp))

// append some more lines
var lines2 = ["four", "five", "six"]
FileUtil.appendLines(tmp, lines2)
System.print("Updated contents of temporary file:")
System.print(File.read(tmp))
File.delete(tmp)
System.print("Temporary file deleted.")</syntaxhighlight>

{{out}}
Sample run:
<pre>
Temporary file path: /tmp/temp574327.tmp
Original contents of temporary file:
one
two
three

Updated contents of temporary file:
one
two
three
four
five
six

Temporary file deleted.
</pre>

=={{header|zkl}}==
zkl uses the underlying OS to create these files, mkstemp (POSIX), _mktemp_s (Windows). Not at all sure Windows is race free however.
{{out}}
<pre>
zkl: File.mktmp()
File(zklTmpFile082p1V)
</pre>


{{omit from|HTML}}
{{omit from|HTML}}

Latest revision as of 10:38, 4 February 2024

Task
Secure temporary file
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Create a temporary file, securely and exclusively (opening it such that there are no possible race conditions).

It's fine assuming local filesystem semantics (NFS or other networking filesystems can have signficantly more complicated semantics for satisfying the "no race conditions" criteria).

The function should automatically resolve name collisions and should only fail in cases where permission is denied, the filesystem is read-only or full, or similar conditions exist (returning an error or raising an exception as appropriate to the language/environment).

Ada

Ada creates a temporary file whenever the create procedure is called without file name. That temporary file is automatically deleted at the end of the program creating the file.

This example creates a temporary file, writes to the file, then reads from the file.

with Ada.Text_Io; use Ada.Text_Io;

procedure Temp_File is
   Temp : File_Type;
   Contents : String(1..80);
   Length : Natural;
begin
   -- Create a temporary file
   Create(File => Temp);
   Put_Line(File => Temp, Item => "Hello World");
   Reset(File => Temp, Mode => In_File);
   Get_Line(File => Temp, Item => Contents, Last => Length);
   Put_Line(Contents(1..Length));  
end Temp_File;

BASIC

BBC BASIC

The file is automatically deleted when closed.

      file% = FNopentempfile
      IF file% = 0 ERROR 100, "Failed to open temp file"
      PRINT #file%, "Hello world!"
      PTR#file% = 0
      INPUT #file%, message$
      CLOSE #file%
      PRINT message$
      END
      
      DEF FNopentempfile
      LOCAL pname%, hfile%, chan%
      OPEN_EXISTING = 3
      FILE_FLAG_DELETE_ON_CLOSE = &4000000
      GENERIC_READ = &80000000
      GENERIC_WRITE = &40000000
      INVALID_HANDLE_VALUE = -1
      DIM pname% LOCAL 260
      FOR chan% = 5 TO 12
        IF @hfile%(chan%) = 0 EXIT FOR
      NEXT
      IF chan% > 12 THEN = 0
      SYS "GetTempFileName", @tmp$, "BBC", 0, pname%
      SYS "CreateFile", $$pname%, GENERIC_READ OR GENERIC_WRITE, 0, 0, \
      \                 OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 TO hfile%
      IF hfile% = INVALID_HANDLE_VALUE THEN = 0
      @hfile%(chan%) = hfile%
      = chan%

Output:

Hello world!

FreeBASIC

Translation of: BBC BASIC

The file is deleted when closed.

Dim As Long f
Dim As String message

f = Freefile
Open "temp.txt" For Output As #f
If Err > 0 Then Print "Failed to open temp"; f : End
Print #f, "Hello world!"
Close #f

Open "temp.txt" For Input As #f
Line Input #f, message
Close #f
Print message

Shell "del temp.txt"

Sleep

C

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
  FILE *fh = tmpfile(); /* file is automatically deleted when program exits */
  /* do stuff with stream "fh" */
  fclose(fh);
  /* The C standard library also has a tmpnam() function to create a file
    for you to open later. But you should not use it because someone else might
    be able to open the file from the time it is created by this function to the
    time you open it. */
  return 0;
}

The following

Works with: POSIX
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
  char filename[] = "/tmp/prefixXXXXXX";
  int fd = mkstemp(filename);
  puts(filename);
  /* do stuff with file descriptor "fd" */
  close(fd);
  return 0;
}

C#

using System;
using System.IO;

Console.WriteLine(Path.GetTempFileName());

==C#==

C++

#include <cstdio>

int main() {
	// Creates and opens a temporary file with a unique auto-generated filename.
    // If the program closes the file, the file is automatically deleted.
	// The file is also automatically deleted if the program exits normally.
    std::FILE* temp_file_pointer = std::tmpfile();

    // Using functions which take a file pointer as an argument
    std::fputs("Hello world", temp_file_pointer);
    std::rewind(temp_file_pointer);
    char buffer[12];
    std::fgets(buffer, sizeof buffer, temp_file_pointer);
    printf(buffer);
}
Output:
Hello world

Clojure

It is good practice to explicitly delete temp files immediately once they've been used.

(let [temp-file (java.io.File/createTempFile "pre" ".suff")]
  ; insert logic here that would use temp-file
  (.delete temp-file))

D

Works with: Tango
module tempfile ;
import tango.io.TempFile, tango.io.Stdout ;

void main(char[][] args) {
  
  // create a temporary file that will be deleted automatically when out of scope
  auto tempTransient = new TempFile(TempFile.Transient) ;
  Stdout(tempTransient.path()).newline ;

  // create a temporary file, still persist after the TempFile object has been destroyed
  auto tempPermanent = new TempFile(TempFile.Permanent) ;
  Stdout(tempPermanent.path()).newline ;  

  // both can only be accessed by the current user (the program?). 
}

Delphi

program Secure_temporary_file;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.IOUtils;

var
  FileName, buf: string;

begin
  FileName := TPath.GetTempFileName;
  with TFile.Open(FileName, TFileMode.fmCreate, TFileAccess.faReadWrite,
    Tfileshare.fsNone) do
  begin
    buf := 'This is a exclusive temp file';
    Write(buf[1], buf.Length * sizeof(char));
    Free;
  end;

  writeln(FileName);
  Readln;
end.

Emacs Lisp

make-temp-file creates a new empty temporary file, with perms "0700" so read-write to the current user only.

(make-temp-file "prefix")
;; => "/tmp/prefix25452LPe"

F#

printfn $"%s{System.IO.Path.GetTempFileName()}"
Output:
/tmp/tmpEuSgiY.tmp

For the cynical who may not believe the file has been created

nigel@nigel:/tmp$ ls *.tmp tmpEuSgiY.tmp


Fortran

Supposing F is an integer variable, whose value might be 10. This is the I/O unit number, and would be used in READ(F,etc. and WRITE(F,etc. statements.

        OPEN (F,STATUS = 'SCRATCH')   !Temporary disc storage.

Other attributes might be specified depending on the intended usage, but note that no file name is given. When the file is closed, its storage vanishes back to the file system.

Following the OPEN statement with INQUIRE (F,NAME = FNAME); WRITE (6,*) FNAME yields C:\DOCUME~1\Nicky\LOCALS~1\Temp\FOR57.tmp which is the DOS style short (8.3) file name for C:\Documents and Settings\Nicky\Local Settings\Temp\FOR57.tmp and the example's numerical value of 57 will be different on another run. Thus, the file could be interfered with, except that a file opened with WRITE access is exclusive-use, and there is no point in opening a SCRATCH file with READONLY (to allow sharing) because it cannot be a pre-existing disc file. However, the actual behaviour of a particular file system and compiler may or may not support such refinements as shared access as implied by non-standard keywords as READONLY, etc.

Go

Use ioutil.TempFile

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	f, err := ioutil.TempFile("", "foo")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// We need to make sure we remove the file
	// once it is no longer needed.
	defer os.Remove(f.Name())

	// … use the file via 'f' …
	fmt.Fprintln(f, "Using temporary file:", f.Name())
	f.Seek(0, 0)
	d, err := ioutil.ReadAll(f)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Wrote and read: %s\n", d)

        // The defer statements above will close and remove the
        // temporary file here (or on any return of this function).
}
Output:
Wrote and read: Using temporary file: /tmp/foo054003078

Groovy

def file = File.createTempFile( "xxx", ".txt" )

// There is no requirement in the instructions to delete the file.
//file.deleteOnExit()

println file

Output:

C:\DOCUME~1\ROGER~1.GLO\LOCALS~1\Temp\xxx8918700806071036530.txt

Haskell

import System.IO

main = do (pathOfTempFile, h) <- openTempFile "." "prefix.suffix" -- first argument is path to directory where you want to put it
          -- do stuff with it here; "h" is the Handle to the opened file
          return ()

HicEst

! The "scratch" option opens a file exclusively for the current process.
! A scratch file is automatically deleted upon process termination.

OPEN( FIle='TemporaryAndExclusive', SCRatch, IOStat=ErrNr)
WRITE(FIle='TemporaryAndExclusive') "something"
WRITE(FIle='TemporaryAndExclusive', CLoSe=1) ! explicit "close" deletes file

! Without "scratch" access can be controlled by "denyread", "denywrite", "denyreadwrite" options.

OPEN( FIle='DenyForOthers', DenyREAdWRIte, IOStat=ErrNr)
WRITE(FIle='DenyForOthers') "something"
WRITE(FIle='DenyForOthers', DELETE=1)

Icon and Unicon

A posix-based solution that works in both languages:

procedure main()
    write("Creating: ",fName := !open("mktemp","rp"))
    write(f := open(fName,"w"),"Hello, world")
    close(f)
end

Java

import java.io.File;
import java.io.IOException;

public class CreateTempFile {
    public static void main(String[] args)  {
        try {
            //create a temp file
            File temp = File.createTempFile("temp-file-name", ".tmp");
            System.out.println("Temp file : " + temp.getAbsolutePath());
        }
        catch(IOException e) {
            e.printStackTrace();
    	}
    }
}

Alternative example

import java.io.BufferedWriter;
import java.nio.file.Files;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public final class SecureTemporaryFile {

    public static void main(String[] args) throws IOException  {
        // Create a temporary file in the directory D:\.
        // We should use java.nio.file.Files instead of the old java.io.File, as it is more secure.
        // If the file cannot be created, it will throw an exception. 
        Path temporaryFilePath = Files.createTempFile(Path.of("D:/"), "example", ".tmp");

        // For uniqueness, the Java API will insert a random number between the given prefix
        // and the file extension. 
        System.out.println("Temporary file created: " + temporaryFilePath);

        // Opening it with the following option will cause the file to be deleted when it is closed.
        BufferedWriter tempFileWriter = Files.newBufferedWriter(
                temporaryFilePath, StandardOpenOption.DELETE_ON_CLOSE);
        // ... write to file, read it back in, close it...
    }

}
Output:
Temporary file created: D:\example12312088502442779987.tmp

Julia

Works with: Linux

On Unix systems, Julia calls mkstemp to securely open a temporary file. This is likely multi-thread safe, check your system documentation for verification. This code should also work on Windows, but I've not verified that.

msg = "Rosetta Code, Secure temporary file, implemented with Julia."

(fname, tio) = mktemp()
println(fname, " created as a temporary file.")
println(tio, msg)
close(tio)
println("\"", msg, "\" written to ", fname)

Files written to \tmp persist for the login session, and are thus truly temporary. If the environment variable TMPDIR is set, the temporary file is created in this directory. In this case, the file may not be properly temporary.

ENV["TMPDIR"] = pwd()
(fname, tio) = mktemp()
println(fname, " created as a \"temporary\" file.")
println(tio, msg)
close(tio)
println("\"", msg, "\" written to ", fname)
Output:
/tmp/tmphe0qlu created as a temporary file.
"Rosetta Code, Secure temporary file, implemented with Julia." written to /tmp/tmphe0qlu
/home/mike/rosetta/julia/tmpVNGK8D created as a "temporary" file.
"Rosetta Code, Secure temporary file, implemented with Julia." written to /home/joeb/rosetta/julia/tmpVNGK8D
$ cat /tmp/tmphe0qlu
Rosetta Code, Secure temporary file, implemented with Julia.
$ ls -l /tmp/tmphe0qlu
-rw------- 1 joeb joeb 61 Apr 13 13:18 /tmp/tmphe0qlu
$ cat tmpVNGK8D
Rosetta Code, Secure temporary file, implemented with Julia.
$ ls -l tmpVNGK8D
-rw------- 1 joeb jeob 61 Apr 13 13:18 tmpVNGK8D

Kotlin

import kotlin.io.path.createTempFile
import kotlin.io.path.deleteExisting

fun main() {
    val tempFilePath = createTempFile("example", ".tmp")
    println("Temporary file created: $tempFilePath")
    tempFilePath.deleteExisting()
}

Sample output:

Output:
Temporary file created: /tmp/example14437465325231438926.tmp

Lua

fp = io.tmpfile()

-- do some file operations

fp:close()

M2000 Interpreter

tmp files automatic deleted when Environment end (per running environment)

Module Checkit {
      \\ we get a tempname$ choosed  from Windows
      a$=tempname$
      Try ok  {
            \\ we can use wide to export in utf-16le
            \\ without wide we export as Ansi (set Local to desired language)
            Rem Locale 1033 ' when no use of wide
            Open a$ for wide output exclusive as #f
                  wait 10
                  \\ Notepad can't open, because we open it for exclusive use
                  Win "Notepad", a$     
                  Print  #f, "something"
                  Print "Press a key";Key$
            Close #f
      }
      If error or not ok then Print Error$
      Win "Notepad", a$
}
Checkit

Mathematica/Wolfram Language

tmp = OpenWrite[]
Close[tmp]

Nanoquery

import Nanoquery.IO

def guaranteedTempFile()
	// create a file object to generate temp file names
	$namegen = new(File)

	// generate a temp filename
	$tempname = $namegen.tempFileName()
	
	// file names are generated with uuids so they shouldn't repeat
	// in the case that they do, generate new ones until the generated
	// filename is unique
	$tempfile = new(File, $tempname)
	while ($tempfile.exists())
		$tempname = $namegen.tempFileName()
		$tempfile = new(File, $tempname)
	end

	// create the file and lock it from writing
	$tempfile.create()
	lock $tempfile.fullPath()

	// return the file reference
	return $tempfile
end

NetRexx

This example is incomplete. JVM Windows related bug workaround JDK-4715154 Please ensure that it meets all task requirements and remove this message.
/* NetRexx */
options replace format comments java crossref symbols binary

runSample(arg)
return

-- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
method makeTempFile(prefix = String, suffix = String null, startDir = String null) -
  public static signals IOException returns File
  if startDir \= null then fStartDir = File(startDir)
  else                     fStartDir = null
  ff = File.createTempFile(prefix, suffix, fStartDir)
  ff.deleteOnExit() -- make sure the file is deleted at termination
  return ff

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
  do
    tempFiles = [ -
      makeTempFile('rexx'), -
      makeTempFile('rexx', '.rex'), -
      makeTempFile('rexx', null, './tmp') -
    ]
    loop fFile over tempFiles
      fName = fFile.getCanonicalPath()
      say 'Temporary file:' fName
      end fFile
  catch ex = IOException
    ex.printStackTrace()
  end
  return

Nim

Works with: Nim version 1.6.0
import std/[os, tempfiles]

let (file, path) = createTempFile(prefix = "", suffix = "")
echo path, " created."
file.writeLine("This is a secure temporary file.")
file.close()
for line in path.lines:
  echo line
removeFile(path)
Output:
/tmp/th7lDdkH created.
This is a secure temporary file.

OCaml

From the module Filename, one can use the functions temp_file or open_temp_file

# Filename.temp_file "prefix." ".suffix" ;;
- : string = "/home/blue_prawn/tmp/prefix.301f82.suffix"

Octave

Octave has several related functions

  [FID, MSG] = tmpfile();    % Return the file ID corresponding to a new temporary 
  filename = tmpnam (...);   % generates temporary file name, but does not open file
  [FID, NAME, MSG] = mkstemp (TEMPLATE, DELETE);    % Return the file ID corresponding to a new temporary file with a unique name created from TEMPLATE.

Pascal

Works with: Free_Pascal
Library: SysUtils
Program TempFileDemo;

uses
  SysUtils;

var
  tempFile: text;

begin
  assign (Tempfile, GetTempFileName);
  rewrite (tempFile);
  writeln (tempFile, 5);
  close (tempFile);
end.

Perl

function interface:

use File::Temp qw(tempfile);
$fh = tempfile();
($fh2, $filename) = tempfile(); # this file stays around by default
print "$filename\n";
close $fh;
close $fh2;

object-oriented interface:

use File::Temp;
$fh = new File::Temp;
print $fh->filename, "\n";
close $fh;

Phix

The temp_file() function (see builtins/pfile.e) can be used for this:

without js -- (file i/o)
pp(temp_file())
{integer fn, string name} = temp_file("myapp/tmp","data","log","wb")
pp({fn,name})
close(fn)
{} = delete_file(name)
Output:
`C:\Users\Pete\AppData\Local\Temp\419750.tmp`
{3, `C:\Program Files (x86)\Phix\myapp\tmp\data408865.log`}

If you don't provide an open mode (one of "w", "wb", "a", or "ab") then there is a 1-in-a-million chance someone else will beat you to the punch; if you do provide one, it will open/loop for you.

PHP

$fh = tmpfile();
// do stuff with $fh
fclose($fh);
// file removed when closed

// or:
$filename = tempnam('/tmp', 'prefix');
echo "$filename\n";
// open $filename and do stuff with it

PicoLisp

The 'tmp' function returns temporary file names which are exclusively for the current process (based on the process ID). These files are automatically deleted upon process termination. Background tasks within a single PicoLisp process is always non-preemptive, therefore dedicated locks are usually not necessary. If they are (e.g. because such a file name is passed to a child process), explicit locks with the 'ctl' functions are possible.

: (out (tmp "foo") (println 123))         # Write tempfile
-> 123

: (in (tmp "foo") (read))                 # Read tempfile
-> 123

: (let F (tmp "foo")
   (ctl F                                 # Get exclusive lock
      (in F 
         (let N (read)                    # Atomic increment
            (out F (println (inc N))) ) ) ) )
-> 124

PowerShell

$tempFile = [System.IO.Path]::GetTempFileName()
Set-Content -Path $tempFile -Value "FileName = $tempFile"
Get-Content -Path $tempFile
Remove-Item -Path $tempFile
Output:
FileName = C:\Users\Owner\AppData\Local\Temp\tmpB68.tmp

PureBasic

Procedure.s TempFile()
  Protected a, Result$

  For a = 0 To 9999
    Result$ = GetTemporaryDirectory() + StringField(GetFilePart(ProgramFilename()),1,".")
    Result$ + "_" + Str(ElapsedMilliseconds()) + "_(" + RSet(Str(a),4,"0") + ").tmp"
    If FileSize(Result$) = -1                                      ;  -1 = File not found
      ProcedureReturn Result$
    EndIf
  Next

  ProcedureReturn ""
EndProcedure


Define File, File$

File$ = TempFile()
If File$ <> ""
  File = CreateFile(#PB_Any, File$)
  If File <> 0
    WriteString(File, "Some temporary data here...")
    CloseFile(File)
  EndIf
EndIf

Python

Works with: Python version 2.3+

In both cases, the temporary file will be deleted automatically when the file is closed. The invisible file will not be accessible on UNIX-like systems. You can use os.link to preserve the visible temporary file contents.


>>> import tempfile
>>> invisible = tempfile.TemporaryFile()
>>> invisible.name
'<fdopen>'
>>> visible = tempfile.NamedTemporaryFile()
>>> visible.name
'/tmp/tmpZNfc_s'
>>> visible.close()
>>> invisible.close()


More low level way, if you have special needs. This was the only option before Python 2.3:


fd, path = tempfile.mkstemp()
try:
    # use the path or the file descriptor
finally:
    os.close(fd)

Racket

#lang racket
(make-temporary-file)

Raku

(formerly Perl 6)

Works with: Rakudo version 2017.09

This is something best done with a module which is heavily tested, tries to account for all corner cases and automatically cleans up after itself.

Almost verbatim from the synopsis:

use File::Temp;

# Generate a temp file in a temp dir
my ($filename0,$filehandle0) = tempfile;

# specify a template for the filename
#  * are replaced with random characters
my ($filename1,$filehandle1) = tempfile("******");

# Automatically unlink files at DESTROY (this is the default)
my ($filename2,$filehandle2) = tempfile("******", :unlink);

# Specify the directory where the tempfile will be created
my ($filename3,$filehandle3) = tempfile(:tempdir("/path/to/my/dir"));

# don't unlink this one
my ($filename4,$filehandle4) = tempfile(:tempdir('.'), :!unlink);

# specify a prefix, a suffix, or both for the filename
my ($filename5,$filehandle5) = tempfile(:prefix('foo'), :suffix(".txt"));

REXX

REXX uses the underlying OS to create and delete the file.

/*REXX pgm secures (a temporary file), writes to it, displays the file, then deletes it.*/
parse arg tFID # .                               /*obtain optional argument from the CL.*/
if tFID=='' | tFID==","  then tFID= 'TEMP.FILE'  /*Not specified?  Then use the default.*/
if    #=='' |    #==","  then    #= 6            /* "      "         "   "   "     "    */
call lineout tFID                                /*insure file is closed.               */
rc= 0
say '··· creating file: '  tFID
call lineout tFID,,1                             /*insure file is open and at record 1. */
if rc\==0  then call ser rc 'creating file' tFID /*issue error if can't open the file.  */
say '··· writing  file: '  tFID

    do j=1  for #                                /*write a half-dozen records to file.  */
    call lineout tFID, 'line' j                  /*write a  record  to the file.        */
    if rc\==0  then call ser rc 'writing file'  tFID    /*Have an error?  Issue err msg.*/
    end   /*j*/

call lineout tFID                                /*close the file.                      */
say '··· reading/display file: '  tFID

    do j=1  while lines(tFID)>0                  /*read the entire file and display it. */
    x= linein(tFID)                              /*read a record from the file.         */
    if rc\==0  then call ser rc 'reading file'  tFID    /*Have an error?  Issue err msg.*/
    say 'line ' j  " of file" tFID":"  x                /*display a record to the term. */
    end   /*j*/

call lineout tFID                                /*close the file.                      */
say '··· erasing file: '  tFID
'ERASE' tFID                                     /*erase the file.                      */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
ser: say; say '***error***' arg(1); say; exit 13 /*issue an error message to the term.  */
output   when using the default input:
··· creating file:  TEMP.FILE
··· writing  file:  TEMP.FILE
··· reading/display file:  TEMP.FILE
line  1  of file TEMP.FILE: line 1
line  2  of file TEMP.FILE: line 2
line  3  of file TEMP.FILE: line 3
line  4  of file TEMP.FILE: line 4
line  5  of file TEMP.FILE: line 5
line  6  of file TEMP.FILE: line 6
··· erasing file:  TEMP.FILE

Ruby

require 'tempfile'

f = Tempfile.new('foo')
f.path  # => "/tmp/foo20081226-307-10p746n-0"
f.close
f.unlink # => #<Tempfile: (closed)>

Rust

// 202100322 Rust programming solution

use tempfile::tempfile;

fn main() {

    let fh = tempfile();

    println!("{:?}", fh);
}
Output:
Ok(File { fd: 3, path: "/tmp/#37224506 (deleted)", read: true, write: true })

Scala

import java.io.{File, FileWriter, IOException}

  def writeStringToFile(file: File, data: String, appending: Boolean = false) =
    using(new FileWriter(file, appending))(_.write(data))

  def using[A <: {def close() : Unit}, B](resource: A)(f: A => B): B =
    try f(resource) finally resource.close()

  try {
    val file = File.createTempFile("_rosetta", ".passwd")
    // Just an example how you can fill a file
    using(new FileWriter(file))(writer => rawDataIter.foreach(line => writer.write(line)))
    scala.compat.Platform.collectGarbage() // JVM Windows related bug workaround JDK-4715154
    file.deleteOnExit()
    println(file)
  } catch {
    case e: IOException => println(s"Running Example failed: ${e.getMessage}")
  }

Sidef

var tmpfile = require('File::Temp');
var fh = tmpfile.new(UNLINK => 0);
say fh.filename;
fh.print("Hello, World!\n");
fh.close;

SparForte

As a structured script.

#!/usr/local/bin/spar
pragma annotate( summary, "tmpfile" );
pragma annotate( description, "Create a temporary file, securely and exclusively" );
pragma annotate( description, "(opening it such that there are no possible race" );
pragma annotate( description, "conditions). It's fine assuming local filesystem" );
pragma annotate( description, "semantics (NFS or other networking filesystems can" );
pragma annotate( description, "have signficantly more complicated semantics for" );
pragma annotate( description, "satisfying the 'no race conditions' criteria). The" );
pragma annotate( description, "function should automatically resolve name collisions" );
pragma annotate( description, "and should only fail in cases where permission is" );
pragma annotate( description, "denied, the filesystem is read-only or full, or similar" );
pragma annotate( description, "conditions exist (returning an error or raising an" );
pragma annotate( description, "exception as appropriate to the language/environment)." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Secure_temporary_file" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );

pragma restriction( no_external_commands );

procedure tmpfile is
   temp : file_type;
   contents : string;
begin
   ? "Creating a temporary file";
   create( temp );
   put_line( temp,  "Hello World");

   ? "Reading a temporary file";
   reset( temp, in_file);
   contents := get_line( temp );
   put_line( "File contains: " & contents );  

   ? "Discarding a temporary file";
   close( temp );
end tmpfile;

Standard ML

val filename = OS.FileSys.tmpName ();

Tcl

Works with: Tcl version 8.6

Will store the name of the file in the variable filenameVar and an open read-write channel on the file in the variable chan.

set chan [file tempfile filenameVar]

Note that because we're asking for the filename in the script, Tcl does not automatically clean the file. (There are cases where auto-cleaning would be really unwanted.) If we hadn't asked for it, the file would be automatically deleted (at a time that depends on platform constraints).

TUSCRIPT

$$ MODE TUSCRIPT
tmpfile="test.txt"
ERROR/STOP CREATE (tmpfile,seq-E,-std-)
text="hello world"
FILE $tmpfile = text
- tmpfile "test.txt" can only be accessed by one user an will be deleted upon programm termination

UNIX Shell

UNIX shell scripts cannot guarantee secure, race-free, exclusive access to an open file descriptor. The best approach to working around this limitation is to create a directory (the mkdir command is a wrapper around the atomic mkdir() system call) and then perform all temporary file operations thereunder.

RESTOREUMASK=$(umask)
TRY=0
while :; do
   TRY=$(( TRY + 1 ))
   umask 0077
   MYTMP=${TMPDIR:-/tmp}/$(basename $0).$$.$(date +%s).$TRY
   trap "rm -fr $MYTMP" EXIT
   mkdir "$MYTMP" 2>/dev/null && break
done
umask "$RESTOREUMASK"
cd "$MYTMP" || {
   echo "Temporary directory failure on $MYTMP" >&2
   exit 1; }

Note that the shell special variable $$ (the PID of the currently exec()-ed shell) is unique at any given moment on a UNIX system, and $(date +%s) gives the time represented as a number of seconds since the UNIX epoch (GNU date or any other with the %s extension). So any name collision here is most likely "enemy action." This code will loop, picking new names and resetting the trap (clean-up command) until it succeeds in making a directory. (Simple changes to the code could limit the number of attempts or implement a timeout).

Wren

Library: Wren-ioutil
Library: Wren-fmt
import "random" for Random
import "./ioutil" for File, FileUtil
import "./fmt" for Fmt

var rand = Random.new()

var createTempFile = Fn.new { |lines|
    var tmp
    while (true) {
        // create a name which includes a random 6 digit number
        tmp = "/tmp/temp%(Fmt.swrite("$06d", rand.int(1e6))).tmp"
        if (!File.exists(tmp)) break
    }
    FileUtil.writeLines(tmp, lines)
    return tmp
}

var lines = ["one", "two", "three"]
var tmp = createTempFile.call(lines)
System.print("Temporary file path: %(tmp)")
System.print("Original contents of temporary file:")
System.print(File.read(tmp))

// append some more lines
var lines2 = ["four", "five", "six"]
FileUtil.appendLines(tmp, lines2)
System.print("Updated contents of temporary file:")
System.print(File.read(tmp))
File.delete(tmp)
System.print("Temporary file deleted.")
Output:

Sample run:

Temporary file path: /tmp/temp574327.tmp
Original contents of temporary file:
one
two
three

Updated contents of temporary file:
one
two
three
four
five
six

Temporary file deleted.

zkl

zkl uses the underlying OS to create these files, mkstemp (POSIX), _mktemp_s (Windows). Not at all sure Windows is race free however.

Output:
zkl: File.mktmp()
File(zklTmpFile082p1V)