29 const char* wfs_file_base::io_type()
const 34 static HANDLE open_file_impl(
const std::string& filename,
int mode)
36 DWORD dwDesiredAccess = 0;
37 DWORD dwShareMode = 0;
38 DWORD dwCreationDisposition = 0;
39 DWORD dwFlagsAndAttributes = 0;
43 dwFlagsAndAttributes |= FILE_ATTRIBUTE_READONLY;
44 dwDesiredAccess |= GENERIC_READ;
49 dwDesiredAccess |= GENERIC_WRITE;
54 dwDesiredAccess |= (GENERIC_READ | GENERIC_WRITE);
64 dwCreationDisposition |= TRUNCATE_EXISTING;
68 dwCreationDisposition |= OPEN_ALWAYS;
73 #if !FOXXLL_DIRECT_IO_OFF 74 dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING;
78 TLX_LOG1 <<
"Error: open()ing " << filename <<
" with DIRECT mode required, but the system does not support it.";
79 return INVALID_HANDLE_VALUE;
82 TLX_LOG1 <<
"Warning: open()ing " << filename <<
" without DIRECT mode, as the system does not support it.";
92 HANDLE file_des_ = ::CreateFileA(
93 filename.c_str(), dwDesiredAccess, dwShareMode,
nullptr,
94 dwCreationDisposition, dwFlagsAndAttributes, nullptr
97 if (file_des_ != INVALID_HANDLE_VALUE)
100 #if !FOXXLL_DIRECT_IO_OFF 103 TLX_LOG1 <<
"CreateFile() error on path=" << filename <<
" mode=" << mode <<
", retrying without DIRECT mode.";
105 dwFlagsAndAttributes &= ~FILE_FLAG_NO_BUFFERING;
107 HANDLE file_des2 = ::CreateFileA(
108 filename.c_str(), dwDesiredAccess, dwShareMode,
nullptr,
109 dwCreationDisposition, dwFlagsAndAttributes, nullptr
112 if (file_des2 != INVALID_HANDLE_VALUE)
117 FOXXLL_THROW_WIN_LASTERROR(io_error,
"CreateFile() path=" << filename <<
" mode=" << mode);
120 wfs_file_base::wfs_file_base(
const std::string& filename,
int mode)
121 : file_des_(INVALID_HANDLE_VALUE),
122 mode_(mode), filename_(filename), locked_(false)
124 file_des_ = open_file_impl(filename, mode);
125 need_alignment_ = (mode& file::DIRECT) != 0;
127 if (!(mode & NO_LOCK))
132 if (!(mode_ & RDONLY) && (mode & DIRECT))
134 char buf[32768], * part;
135 if (!GetFullPathNameA(filename.c_str(),
sizeof(buf), buf, &part))
137 TLX_LOG1 <<
"wfs_file_base::wfs_file_base(): GetFullPathNameA() error for file " << filename;
138 bytes_per_sector_ = 512;
143 DWORD bytes_per_sector_;
144 if (!GetDiskFreeSpaceA(buf,
nullptr, &bytes_per_sector_,
nullptr,
nullptr))
146 TLX_LOG1 <<
"wfs_file_base::wfs_file_base(): GetDiskFreeSpaceA() error for path " << buf;
147 bytes_per_sector_ = 512;
150 bytes_per_sector_ = bytes_per_sector_;
155 wfs_file_base::~wfs_file_base()
160 void wfs_file_base::close()
162 std::unique_lock<std::mutex> fd_lock(fd_mutex_);
164 if (file_des_ == INVALID_HANDLE_VALUE)
167 if (!CloseHandle(file_des_))
168 FOXXLL_THROW_WIN_LASTERROR(io_error,
"CloseHandle() of file fd=" << file_des_);
170 file_des_ = INVALID_HANDLE_VALUE;
173 void wfs_file_base::lock()
175 std::unique_lock<std::mutex> fd_lock(fd_mutex_);
178 if (LockFile(file_des_, 0, 0, 0xffffffff, 0xffffffff) == 0)
179 FOXXLL_THROW_WIN_LASTERROR(io_error,
"LockFile() fd=" << file_des_);
183 file::offset_type wfs_file_base::_size()
185 LARGE_INTEGER result;
186 if (!GetFileSizeEx(file_des_, &result))
187 FOXXLL_THROW_WIN_LASTERROR(io_error,
"GetFileSizeEx() fd=" << file_des_);
189 return result.QuadPart;
192 file::offset_type wfs_file_base::size()
194 std::unique_lock<std::mutex> fd_lock(fd_mutex_);
198 void wfs_file_base::set_size(offset_type newsize)
200 std::unique_lock<std::mutex> fd_lock(fd_mutex_);
201 offset_type cur_size = _size();
203 if (!(mode_ & RDONLY))
205 LARGE_INTEGER desired_pos;
206 desired_pos.QuadPart = newsize;
208 bool direct_with_bad_size = (mode_& file::DIRECT) && (newsize % bytes_per_sector_);
209 if (direct_with_bad_size)
211 if (!CloseHandle(file_des_))
212 FOXXLL_THROW_WIN_LASTERROR(io_error,
"closing file (call of ::CloseHandle() from set_size) ");
214 file_des_ = INVALID_HANDLE_VALUE;
215 file_des_ = open_file_impl(filename_, WRONLY);
218 if (!SetFilePointerEx(file_des_, desired_pos,
nullptr, FILE_BEGIN))
219 FOXXLL_THROW_WIN_LASTERROR(
221 "SetFilePointerEx() in wfs_file_base::set_size(..) oldsize=" << cur_size <<
222 " newsize=" << newsize <<
" " 225 if (!SetEndOfFile(file_des_))
226 FOXXLL_THROW_WIN_LASTERROR(
227 io_error,
"SetEndOfFile() oldsize=" << cur_size <<
228 " newsize=" << newsize <<
" " 231 if (direct_with_bad_size)
233 if (!CloseHandle(file_des_))
234 FOXXLL_THROW_WIN_LASTERROR(io_error,
"closing file (call of ::CloseHandle() from set_size) ");
236 file_des_ = INVALID_HANDLE_VALUE;
237 file_des_ = open_file_impl(filename_, mode_ & ~TRUNC);
242 void wfs_file_base::close_remove()
245 ::DeleteFileA(filename_.c_str());
250 #endif // FOXXLL_WINDOWS
only reading of the file is allowed
only writing of the file is allowed
implies DIRECT, fail if opening with DIRECT flag does not work.
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
once file is opened its length becomes zero
read and write of the file are allowed
open the file with O_SYNC | O_DSYNC | O_RSYNC flags set