Opened 13 years ago

Closed 12 years ago

#3323 closed Bugs (fixed)

file_descriptor_sink sink("abc", BOOST_IOS::trunc) not trunc

Reported by: qiaozhiqiang@… Owned by: Jonathan Turkanis
Milestone: Boost 1.40.0 Component: iostreams
Version: Boost 1.39.0 Severity: Problem
Keywords: file_descriptor_sink not trunc Cc:

Description

boost 1.39.0 iostreams, on Windows Vista sp2: file_descriptor_sink sink("abc", BOOST_IOS::trunc) not trunc,

and file_descriptor_sink sink("abc", BOOST_IOS::app) only need call SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END) once, but now every write() call it once, why? if write only, can we call SetFilePointer() in open() only once, and not set the flag impl::append?

void file_descriptor::open

( const std::string& path, BOOST_IOS::openmode m,

BOOST_IOS::openmode base )

{

using namespace std; m |= base;

#ifdef BOOST_IOSTREAMS_WINDOWS ---------------------------------------------

DWORD dwDesiredAccess; DWORD dwCreationDisposition; if ( (m & (BOOST_IOS::in | BOOST_IOS::out))

==

(BOOST_IOS::in | BOOST_IOS::out) )

{

if (m & BOOST_IOS::app)

throw BOOST_IOSTREAMS_FAILURE("bad open mode");

dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; dwCreationDisposition =

(m & BOOST_IOS::trunc) ?

OPEN_ALWAYS : OPEN_EXISTING;

} else if (m & BOOST_IOS::in) {

if (m & (BOOST_IOS::app |BOOST_IOS::trunc))

throw BOOST_IOSTREAMS_FAILURE("bad open mode");

dwDesiredAccess = GENERIC_READ; dwCreationDisposition = OPEN_EXISTING;

} else if (m & BOOST_IOS::out) {

dwDesiredAccess = GENERIC_WRITE; dwCreationDisposition = OPEN_ALWAYS; if (m & BOOST_IOS::app)

pimpl_->flags_ |= impl::append;

} else {

throw BOOST_IOSTREAMS_FAILURE("bad open mode");

}

HANDLE handle =

::CreateFileA( path.c_str(),

dwDesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, lpSecurityAttributes dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL ); hTemplateFile

if (handle != INVALID_HANDLE_VALUE) {

pimpl_->handle_ = handle; pimpl_->flags_ |= impl::close_on_exit;

} else {

pimpl_->flags_ = 0; throw BOOST_IOSTREAMS_FAILURE("bad open");

}

..................

std::streamsize file_descriptor::write(const char_type* s, std::streamsize n) { #ifdef BOOST_IOSTREAMS_WINDOWS

if (pimpl_->flags_ & impl::append) {

DWORD const dwResult =

::SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END);

if ( dwResult == INVALID_SET_FILE_POINTER &&

::GetLastError() != NO_ERROR )

{

throw detail::bad_seek();

}

} DWORD ignore; if (!::WriteFile(pimpl_->handle_, s, n, &ignore, NULL))

throw detail::bad_write();

return n;

...............

Change History (2)

comment:1 by Steven Watanabe, 12 years ago

(In [62934]) Rejigger file_descriptors handling of std::ios_base::openmode to match std::fstream. In particular, truncate existing files, if std::ios_base::trunc is passed. Refs #3323.

comment:2 by Steven Watanabe, 12 years ago

Resolution: fixed
Status: newclosed

(In [62935]) Open files in append mode on Windows instead of seeking to the end at every write when std::ios_base::app is passed. Fixes #3323.

Note: See TracTickets for help on using tickets.