Crate sync_file

source ·
Expand description

Files that can be read concurrently.

std::fs::File is Sync but reading concurrently from it results in race conditions, because the OS has a single cursor which is advanced and used by several threads.

SyncFile solves this problem by using platform-specific extensions to do positional I/O, so the cursor of the file is not shared. Note that writing concurrently at the same position in a file can still result in race conditions, but only on the content, not the position.

This library also exposes platform-independant fonctions for positional I/O.

§Example

use std::io::Read;
use sync_file::SyncFile;

/// Reads a file byte by byte.
/// Don't do this in real code !
fn read_all<R: Read>(mut file: R) -> std::io::Result<Vec<u8>> {
    let mut result = Vec::new();
    let mut buf = [0];

    while file.read(&mut buf)? != 0 {
        result.extend(&buf);
    }

    Ok(result)
}

// Open a file
let f = SyncFile::open("hello.txt")?;
let f_clone = f.clone();

// Read it concurrently
let thread = std::thread::spawn(move || read_all(f_clone));
let res1 = read_all(f)?;
let res2 = thread.join().unwrap()?;

// Both clones read the whole content
// This would not work with `std::fs::File`
assert_eq!(res1, b"Hello World!\n");
assert_eq!(res2, b"Hello World!\n");

§OS support

Windows and Unix targets provide extensions for positional I/O, so on these targets SyncFile is zero-cost. Wasi also provide these but only with a nightly compiler.

If platform-specific extensions are not available, SyncFile fallbacks to a mutex.

Structs§

  • An adapter that implement std::io traits.
  • A file with cross-platform positioned I/O.
  • A file wrapper that is safe to use concurrently.

Traits§

  • The ReadAt trait allows for reading bytes from a source at a given offset.
  • The WriteAt trait allows for writing bytes to a source at a given offset.