Function updateFile [src]
Check the file size, mtime, and mode of source_path and dest_path. If they are equal, does nothing.
Otherwise, atomically copies source_path to dest_path. The destination file gains the mtime,
atime, and mode of the source file so that the next call to updateFile will not need a copy.
Returns the previous status of the file before updating.
If any of the directories do not exist for dest_path, they are created.
On Windows, both paths should be encoded as WTF-8.
On WASI, both paths should be encoded as valid UTF-8.
On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
Prototype
pub fn updateFile( source_dir: Dir, source_path: []const u8, dest_dir: Dir, dest_path: []const u8, options: CopyFileOptions, ) !PrevStatus
Parameters
source_dir: Dir
source_path: []const u8
dest_dir: Dir
dest_path: []const u8
options: CopyFileOptions
Source
pub fn updateFile(
source_dir: Dir,
source_path: []const u8,
dest_dir: Dir,
dest_path: []const u8,
options: CopyFileOptions,
) !PrevStatus {
var src_file = try source_dir.openFile(source_path, .{});
defer src_file.close();
const src_stat = try src_file.stat();
const actual_mode = options.override_mode orelse src_stat.mode;
check_dest_stat: {
const dest_stat = blk: {
var dest_file = dest_dir.openFile(dest_path, .{}) catch |err| switch (err) {
error.FileNotFound => break :check_dest_stat,
else => |e| return e,
};
defer dest_file.close();
break :blk try dest_file.stat();
};
if (src_stat.size == dest_stat.size and
src_stat.mtime == dest_stat.mtime and
actual_mode == dest_stat.mode)
{
return PrevStatus.fresh;
}
}
if (fs.path.dirname(dest_path)) |dirname| {
try dest_dir.makePath(dirname);
}
var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available.
var atomic_file = try dest_dir.atomicFile(dest_path, .{
.mode = actual_mode,
.write_buffer = &buffer,
});
defer atomic_file.deinit();
var src_reader: File.Reader = .initSize(src_file, &.{}, src_stat.size);
const dest_writer = &atomic_file.file_writer.interface;
_ = dest_writer.sendFileAll(&src_reader, .unlimited) catch |err| switch (err) {
error.ReadFailed => return src_reader.err.?,
error.WriteFailed => return atomic_file.file_writer.err.?,
};
try atomic_file.flush();
try atomic_file.file_writer.file.updateTimes(src_stat.atime, src_stat.mtime);
try atomic_file.renameIntoPlace();
return .stale;
}