|
Boost : |
From: Alberto Barbati (abarbati_at_[hidden])
Date: 2003-01-01 13:08:30
Hi,
first of all, I want to thank Beman Dawes and all others that
contributed with the design and development of the Filesystem library.
It's a wonderful piece of work.
I just would like to propose a couple of additions that I believe are
very useful. Both features regard temporary files.
First proposal: I propose to add a function with a signature of this kind:
path generate_path_for_temp_file();
the effect would be to generate a new (potentially unique) path suitable
to be used for a temporary files. A sample POSIX implementation could be
as simple as:
#include <cstdio>
path generate_path_for_temp_file()
{
char tmp_name[L_tmpnam];
return path(tmpname(tmp_name), native);
}
but there could also be platform-specific implementations. For example,
a Win32 sample implementation could use the GetTempPath/GetTempFileName
to create the path in the correct directory as in:
#include <windows.h>
path generate_path_for_temp_file()
{
char tmp_dir_path[MAX_PATH];
char tmp_name[MAX_PATH];
if(GetTempPathA(sizeof(tmp_dir_path), tmp_dir_path) == 0
|| GetTempFileNameA(tmp_dir_path, "$$$", 0, tmp_name) == 0)
{
boost::throw_exception(
filesystem_error("unable to generate path for temporary
file", system_error));
}
return path(tmp_name, native);
}
Open issues (to be discussed):
1) on Win32, GetTempFileName also create an empty file with the returned
name. Other platforms also have functions that atomically generates the
name *and* creates a file with such name. Should there be a
postcondition about the existence (or non-existence) of such a file?
2) Another useful signature could be:
path generate_path_for_temp_file(const path& location_hint)
that would use the specified path as a hint (in an unspecified
platform-dependent way) to generate the path. For example, one may want
to generate a temporary file in a specified directory or physical drive,
overriding the system default, if any. On Win32 such a function could be
implemented as:
#include <windows.h>
path generate_path_for_temp_file(const path& hint)
{
char tmp_name[MAX_PATH];
if(GetTempFileNameA(hint.native_directory_string().c_str(),
"$$$", 0, tmp_name) == 0)
{
boost::throw_exception(
filesystem_error("unable to generate path for temporary
file", system_error));
}
return path(tmp_name, native);
}
Second proposal: a stream class that encapsulates a temporary file, that
is a stream based on a file that is automatically deleted in the
stream's destructor. I am attaching a sample implementation. It's
implemented as a simple wrapper around fs::basic_fstream and
generate_path_for_temp() above.
Cheers,
Alberto
#ifndef BOOST_FILESYSTEM_TEMPSTREAM_HPP
#define BOOST_FILESYSTEM_TEMPSTREAM_HPP
#include <boost/filesystem/fstream.hpp>
namespace boost
{
namespace filesystem
{
path generate_path_for_temp_file();
path generate_path_for_temp_file(const path& hint);
template < class charT, class traits = std::char_traits<charT> >
class basic_tempstream : public basic_fstream<charT, traits>
{
public:
// ctor always opens file
explicit basic_tempstream(std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out)
: m_path(generate_path_for_temp_file())
{
basic_fstream<charT, traits>::open(m_path, mode);
}
explicit basic_tempstream(const path& hint,
std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out)
: m_path(generate_path_for_temp_file(hint))
{
basic_fstream<charT, traits>::open(m_path, mode);
}
virtual ~basic_tempstream()
{
remove(m_path);
}
// intentionally hide inherited open()
void open(std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out)
{
basic_fstream<charT, traits>::open(m_path, mode);
}
const path& path() const
{
return m_path;
}
private:
filesystem::path m_path;
};
typedef basic_tempstream<char> tempstream;
# ifndef BOOST_NO_STD_WSTRING
typedef basic_tempstream<wchar_t> wtempstream;
# endif
} // namespace filesystem
} // namespace boost
#endif // BOOST_FILESYSTEM_TEMPSTREAM_HPP
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk