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
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost