Last active
July 17, 2022 19:17
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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