Skip to content
/ tmp Public

RAII-wrappers for unique temporary files and directories for modern C++

License

Notifications You must be signed in to change notification settings

bugdea1er/tmp

Repository files navigation

tmp

RAII-wrappers for unique temporary files and directories that are deleted automatically for C++17 and later.

This library provides functionality for efficient management of temporary files and directories in long-running applications, automatically deleting them as soon as your app is done with them to optimize resource management.

Static Badge GitHub Tag

Overview

When developing applications with long uptimes, such as server software, the management of temporary files and directories can become crucial. While the system may eventually clean up temporary files, this process may not occur frequently enough to meet the needs of applications with extended operational periods. Relying solely on the system for this task may lead to an accumulation of unnecessary temporary data on the device.

To address this challenge, this library provides functionality for creating temporary files and directories that are automatically deleted as soon as the application finishes using them. This ensures efficient resource management and prevents unnecessary clutter. Even in the event of a crash, the system will eventually clean up any temporary files created by this library, ensuring a seamless user experience and optimal performance.

The location of temporary files generated by this library is determined by the std::filesystem::temp_directory_path function.

This library has been tested on:

  • macOS
  • Linux systems (e.g. Ubuntu Linux, Arch Linux, etc.)
  • FreeBSD (and should work on other BSD systems too)
  • Windows

Features

Temporary directories

tmp::directory is a RAII-handle for unique temporary directories. This can be useful for:

  1. Batch Processing: Temporary directories can be used during batch processing tasks where multiple files need to be processed in a specific order. For example, a script that processes a large number of images may create temporary directories to organize and manage the input and output files efficiently.

  2. Software Installation: Temporary directories are commonly used during software installation processes to store temporary files needed for installation. For instance, when installing a new application, temporary directories can be used to extract installation packages and store temporary configuration files.

  3. Data Backup: Temporary directories can be utilized for creating temporary backups of important data before performing critical operations. For example, before making changes to a database, a temporary directory can be used to store a backup copy of the database to ensure data integrity.

  4. File Compression: Temporary directories are often used during file compression tasks where multiple files need to be compressed into a single archive. For instance, when creating a zip file containing multiple documents, a temporary directory can be used to store the compressed files before creating the final archive.

  5. Data Migration: Temporary directories can be helpful during data migration processes where data needs to be transferred from one system to another. For example, when migrating data from a legacy system to a new system, temporary directories can be used to stage and process the data before final migration.

#include <tmp/directory>
...
{
    // Create a unique temporary directory
    auto tmpdir = tmp::directory("org.example.product");

    // Populate this directory
    fs::copy(file1, tmpdir);
    fs::copy(file2, tmpdir);

    // Make an archive from this directory
    archiver::zip(tmpdir);
}   // The directory will be deleted when exiting the scope

Temporary files

tmp::file is a RAII-handle for unique temporary files. This can be useful for:

  1. Caching: Temporary files can be used to cache data that needs to be accessed frequently but doesn't need to be stored permanently. For example, a web application can store pre-rendered HTML pages in temporary files to improve performance by serving them quickly without re-generating them each time.

  2. Data Processing: Temporary files are often used during data processing tasks where intermediate results need to be stored temporarily before further processing. For instance, a script that manipulates a large dataset may write intermediate results to temporary files to avoid memory constraints.

  3. File Conversion: Temporary files can be utilized during file format conversions. For instance, when converting a video file from one format to another, temporary files can be used to store the partially converted data before completing the conversion process.

  4. Testing: Temporary files can be handy during testing scenarios where you need to create mock data or simulate certain conditions. For example, a unit test for a file upload feature might create a temporary file to mimic the behavior of an uploaded file without actually saving it permanently.

  5. Logging: Temporary files can also be used for logging purposes, where log data is written to a temporary file before being processed and stored in a more permanent location. This can be helpful for managing log data efficiently in high-traffic systems.

#include <tmp/file>
...
{
    // Create a unique temporary file
    auto tmpfile = tmp::file("org.example.product", ".txt");

    // Write its contents and metadata
    tmpfile.write(contents);
    tmpfile.append(metadata);

    // Validate the file with an external validator
    if (validate(tmpfile)) {
        // Save the file to the persistent storage
        tmpfile.move(storage / "new_file");
    } else {
        throw InvalidRequestError();
    }
}   // The file will be deleted when exiting the scope

Building

To build the project without tests, use the -DBUILD_TESTING=OFF flag:

cmake -B build -DBUILD_TESTING=OFF && cmake --build build

To build the project with tests, run:

cmake -B build && cmake --build build --target tmp.test

To run tests:

ctest --output-on-failure --test-dir build

Installing

To install the project, configure it in the Release configuration:

cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON

build it:

cmake --build build

and then install:

sudo cmake --install build

OR use dpkg package manager (requires dpkg-shlibdeps):

cd build && cpack -G DEB && sudo dpkg -i *.deb

OR use rpm package manager (requires rpmbuild):

cd build && cpack -G RPM && sudo rpm -i *.rpm

Package managers

If you are using homebrew, use the following command:

brew install bugdea1er/tap/tmp

Integration

CMake integration

You can also use the CMake interface target tmp::tmp and described below:

External

To use this library from a CMake project, locate it using find_package:

find_package(tmp REQUIRED)
# ...
add_library(foo ...)
target_link_libraries(foo PUBLIC tmp::tmp)

Embedded

To embed the library into your existing CMake project, place the entire source tree in a subdirectory (for example, using git submodule commands) and call add_subdirectory() in your CMakeLists.txt file:

add_subdirectory(tmp)
# ...
add_library(foo ...)
target_link_libraries(foo PUBLIC tmp::tmp)

FetchContent

You can also use the FetchContent functions to automatically download a dependency. Put this in your CMakeLists.txt file:

include(FetchContent)

FetchContent_Declare(tmp URL https://github.com/bugdea1er/tmp/releases/download/<version>/tmp.tar.xz)
FetchContent_MakeAvailable(tmp)

target_link_libraries(foo PUBLIC tmp::tmp)

Contributing

Contributions are always welcome!