Temporary Files And Directories in Erlang

-module(temporary_files_and_directories).
-export([main/0]).

main() ->
    % The easiest way to create a temporary file is by using
    % the tempfile:tempfile/0 function. It creates a file and
    % opens it for reading and writing.
    {ok, {F, Fname}} = tempfile:tempfile(),
    
    % Display the name of the temporary file. On Unix-based OSes
    % the directory will likely be /tmp. The file name is chosen
    % automatically to ensure that concurrent calls will always
    % create different file names.
    io:format("Temp file name: ~s~n", [Fname]),
    
    % Clean up the file after we're done. The OS is likely to
    % clean up temporary files by itself after some time, but
    % it's good practice to do this explicitly.
    on_exit(fun() -> file:delete(Fname) end),
    
    % We can write some data to the file.
    ok = file:write(F, <<1, 2, 3, 4>>),
    
    % If we intend to create many temporary files, we may prefer
    % to create a temporary directory. tempfile:tempdir/0 returns
    % a directory name.
    {ok, Dname} = tempfile:tempdir(),
    io:format("Temp dir name: ~s~n", [Dname]),
    
    % Clean up the directory after we're done.
    on_exit(fun() -> os:cmd("rm -rf " ++ Dname) end),
    
    % Now we can synthesize temporary file names by prefixing
    % them with our temporary directory.
    Fname2 = filename:join(Dname, "file1"),
    ok = file:write_file(Fname2, <<1, 2>>).

% Helper function to register cleanup tasks
on_exit(Fun) ->
    spawn(fun() ->
        process_flag(trap_exit, true),
        receive
            {'EXIT', _From, _Reason} ->
                Fun()
        end
    end),
    link(whereis(init)).

In this Erlang code:

  1. We use the tempfile module, which is not part of the standard library but can be easily implemented or found in community libraries.

  2. Instead of os.CreateTemp, we use tempfile:tempfile/0 to create a temporary file.

  3. For creating a temporary directory, we use tempfile:tempdir/0 instead of os.MkdirTemp.

  4. We use file:write/2 and file:write_file/2 for writing to files, which are similar to Go’s f.Write and os.WriteFile.

  5. For cleanup, we implement an on_exit/1 function that spawns a process which will execute the cleanup function when the main process exits. This is similar to Go’s defer, but works differently due to Erlang’s concurrency model.

  6. We use filename:join/2 instead of filepath.Join to create file paths.

  7. For removing the temporary directory, we use os:cmd/1 to execute a shell command, as Erlang doesn’t have a built-in recursive directory removal function.

To run this program:

$ erlc temporary_files_and_directories.erl
$ erl -noshell -s temporary_files_and_directories main -s init stop
Temp file name: /tmp/erlang-tempfile-1-4504818.txt
Temp dir name: /tmp/erlang-tempdir-1-4504818

Note that the exact output will vary as temporary file and directory names are generated uniquely each time the program runs.