Home | Libraries | People | FAQ | More |
Synchronous data write after a preceding operation, where offset and total data written must not exceed the present file size.
Related types:
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).
io_req
template<class T> void write(future<> _precondition, T && v, off_t _where)
Type |
Concept |
Name |
Description |
---|---|---|---|
class T |
Any type. |
- |
Must be specified |
future<> |
_precondition |
The precondition to use. |
|
T && |
v |
Some item understood by |
|
off_t |
_where |
The file offset to do the i/o |
#include <boost/afio/v2/afio.hpp>
Amortised O(1) to dispatch. Amortised O(1) to complete if writing data is constant time.
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.
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(); // 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();