Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
write (length specifying throwing)

Synchronous data write after a preceding operation, where offset and total data written must not exceed the present file size.

Description

Related types: io_req Note that on Windows this call issues a separate async file operation for each buffer supplied, thus making scatter/gather i/o no more efficient than making separate calls. The big exception to this is when doing unbuffered page aligned i/o for which Windows provides special scatter/gather i/o functions. You should therefore assume that only each buffer is atomically read or written rather than the full sequence of buffers at once (this also applies to POSIX systems without the preadv()/pwritev() operations).

Synopsis
template<class T>
void write(future<> _precondition, T && v, size_t _length,
           off_t _where)
Parameters

Type

Concept

Name

Description

class T

Any type.

-

Must be specified

future<>

_precondition

The precondition to use.

T &&

v

Some item understood by to_asio_buffers()

size_t

_length

The length of the item

off_t

_where

The file offset to do the i/o

Header

#include <boost/afio/v2/afio.hpp>

Complexity

Amortised O(1) to dispatch. Amortised O(1) to complete if writing data is constant time.

Exception Model

Propagates the exception of any input precondition with an errored state at the point of dispatch, and throws a std::invalid_argument if any inputs have values which could not possibly be correct. Note that error code returning functions may still throw exceptions e.g. failure to allocate memory.

Example
namespace afio = BOOST_AFIO_V2_NAMESPACE;
namespace asio = BOOST_AFIO_V2_NAMESPACE::asio;

// Set a dispatcher as current for this thread
afio::current_dispatcher_guard h(afio::make_dispatcher().get());

// Schedule an opening of a file called example_file.txt
afio::future<> openfile = afio::async_file(
"example_file.txt", afio::file_flags::create | afio::file_flags::read_write);

// Something a bit surprising for many people is that writing off
// the end of a file in AFIO does NOT extend the file and writes
// which go past the end will simply fail instead. Why not?
// Simple: that's the convention with async file i/o, because
// synchronising multiple processes concurrently adjusting a
// file's length has significant overhead which is wasted if you
// don't need that functionality. Luckily, there is an easy
// workaround: either open a file for append-only access, in which
// case all writes extend the file for you, or else you explicitly
// extend files before writing, like this:
afio::future<> resizedfile = afio::async_truncate(openfile, 12);

// Config a write gather. You could do this of course as a batch
// of writes, but a write gather has optimised host OS support in most
// cases, so it's one syscall instead of many.
std::vector<asio::const_buffer> buffers;
buffers.push_back(asio::const_buffer("He", 2));
buffers.push_back(asio::const_buffer("ll", 2));
buffers.push_back(asio::const_buffer("o ", 2));
buffers.push_back(asio::const_buffer("Wo", 2));
buffers.push_back(asio::const_buffer("rl", 2));
buffers.push_back(asio::const_buffer("d\n", 2));
// Schedule the write gather to offset zero after the resize file
afio::future<> written(afio::async_write(resizedfile, buffers, 0));

// Have the compiler config the exact same write gather as earlier for you
// The compiler assembles an identical sequence of ASIO write gather
// buffers for you
std::vector<std::string> buffers2 = {"He", "ll", "o ", "Wo", "rl", "d\n"};
// Schedule this to occur after the previous write completes
afio::future<> written2(afio::async_write(written, buffers2, 0));

// Schedule making sure the previous batch has definitely reached physical
// storage
// This won't complete until the write is on disc
afio::future<> stored(afio::async_sync(written2));

// Schedule filling this array from the file. Note how convenient std::array
// is and completely replaces C style char buffer[bytes]
std::array<char, 12> buffer;
afio::future<> read(afio::async_read(stored, buffer, 0));

// Schedule the closing and deleting of example_file.txt after the contents read
afio::future<> deletedfile(afio::async_rmfile(afio::async_close(read)));

// Wait until the buffer has been filled, checking all steps for errors
afio::when_all_p(openfile, resizedfile, written, written2, stored, read)
.get(); 1

// There is actually a io_req<std::string> specialisation you
// can use to skip this bit by reading directly into a string ...
std::string contents(buffer.begin(), buffer.end());
std::cout << "Contents of file is '" << contents << "'" << std::endl;

// Check remaining ops for errors
deletedfile.get();

1

waits for file open, resize, write, sync and read to complete, throwing any exceptions encountered


PrevUpHomeNext