Buffered file to do direct IO reads.
Buffered file to do direct I/O writes.
http://web.archive.org/web/20160317032821/http://www.westnet.com/~gsmith/content/linux-pdflush.htm https://www.kernel.org/doc/Documentation/sysctl/vm.txt
Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. Alternatively, this file may be distributed under the terms of the Tango 3-Clause BSD License (see LICENSE_BSD.txt for details).
Copyright (c) 2009-2016 dunnhumby Germany GmbH. All rights reserved.
Direct I/O output and input streams
This module provides an OutputStream (BufferedDirectWriteFile) and a InputStream (BufferedDirectReadFile) to do direct I/O using Linux's O_DIRECT flag.
This kind of I/O is specially (and probably only) useful when you need to dump a huge amount of data to disk as some kind of backup, i.e., data that you'll probably won't ever read again (or at least in the short term). In those cases, going through the page cache is not only probably slower (because you are doing an extra memory copy), but it can potentially freeze the whole system, if the sysctl vm.dirty_ratio is passed, in that, programs will use their own time to write the page cache to disk. If the data you need to write is small or you are going access it in the short term and you are not experiencing freezes, you probably DON'T want to use this module.
Even when these kind of objects should probably derive from File (i.e. be a device, and be selectable), given this type of I/O is very particular, and a lot of details need to be taken into account, they are just implementing the stream interfaces, and separately (for example, direct I/O is supposed to be always blocking, unless you do async I/O too, because the data is being copied directly from your buffer to the disk, is not going through the page cache, which makes non-blocking I/O possible). Even some of the stream interface methods are not implemented (seek(), flush(), copy() and load()). This might change in the future, if needed.
Direct I/O also must write complete sectors. This means buffers passed to write(2) must be aligned to the block size too. This is why this class uses internal buffering instead of using the original memory. This is just to make user's lives easier, so they don't have to worry about alignment (if you can, try to keep your buffers aligned though, there are optimizations to avoid copies in those cases). When instantiating the classes, it is safe to pass as buffer memory you just allocated through the GC, since the GC returns memory that's always aligned to the page size (4096) when allocating chunks larger than a page.
Users must notice, though, that whole sectors will be written (512 bytes each), so if they write, for example 100 bytes, the file will be still 512 bytes long and the final 412 bytes will contain garbage. truncate(2) or ftruncate(2) might be used to truncate the file to its real size if desired.