Skip to content

Instantly share code, notes, and snippets.

@ptupitsyn
Last active July 17, 2022 19:17
Show Gist options
  • Save ptupitsyn/e9f5287228c01f39c9d6135467ccfd57 to your computer and use it in GitHub Desktop.
Save ptupitsyn/e9f5287228c01f39c9d6135467ccfd57 to your computer and use it in GitHub Desktop.
Linux Dir Sync - copy files to external HDD on Linux with sync command after every file
using System.Diagnostics;
using System.Runtime.InteropServices;
var cts = new CancellationTokenSource();
var cancelEvt = new ManualResetEventSlim();
Console.CancelKeyPress += delegate {
cts.Cancel();
cancelEvt.Wait();
};
const string src = "/media/pavel/DATA_4G/BACKUP/NAXAH-PC";
const string dst = "/media/pavel/New Volume/BACKUP/NAXAH-PC";
var count = 0;
long totalSize = 0;
var sw = Stopwatch.StartNew();
var existingDirs = new HashSet<string>();
foreach (var srcFile in Directory.EnumerateFiles(src, "*", new EnumerationOptions { RecurseSubdirectories = true }))
{
var relPath = Path.GetRelativePath(src, srcFile);
var dstFile = Path.Combine(dst, relPath);
if (File.Exists(dstFile))
{
continue;
}
var dstDir = Path.GetDirectoryName(dstFile)!;
if (!existingDirs.Contains(dstDir))
{
if (!Directory.Exists(dstDir))
{
Directory.CreateDirectory(dstDir);
}
existingDirs.Add(dstDir);
}
Console.Write(DateTime.Now + " " + relPath);
File.Copy(srcFile, dstFile);
Console.Write(" ... ");
// Avoid USB stall on Linux due to huge dirty page queue.
// https://lwn.net/Articles/572911/
NativeMethodsLinux.sync();
var info = new FileInfo(srcFile);
count++;
totalSize += info.Length;
var totalSizeMib = totalSize / 1024 / 1024;
var mibps = (double)totalSizeMib / sw.ElapsedMilliseconds * 1000;
Console.WriteLine($"OK ({count} files, {totalSizeMib} MiB, {sw.Elapsed} elapsed, {mibps} MiB/s)");
if (cts.IsCancellationRequested)
{
Console.WriteLine("Cancelled, exiting...");
cancelEvt.Set();
break;
}
}
static class NativeMethodsLinux
{
[DllImport("libdl.so", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
internal static extern void sync();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment