Skip to content

Instantly share code, notes, and snippets.

@Ellyll
Created Jan 19, 2020
Embed
What would you like to do?
Cymharu ffolderi gyda sgript F# (heb gorffen)
open System.IO
type MathLlwybr =
| File of Length: int64
| Directory
//let llwybr1 = fsi.CommandLineArgs.ElementAt(1)
let dirChars = [| Path.DirectorySeparatorChar ; Path.AltDirectorySeparatorChar |] |> Array.distinct
let nolMathLlwybr (fsInfo: FileSystemInfo) =
if fsInfo :? DirectoryInfo then
MathLlwybr.Directory
elif fsInfo :? FileInfo then
let fInfo = fsInfo :?> FileInfo
MathLlwybr.File (fInfo.Length)
else
failwithf "Unknown type of FileSystemInfo for path: %s" fsInfo.FullName
let nolFfeiliau llwybr =
let dirInfo = DirectoryInfo(llwybr)
dirInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories)
|> Seq.map (fun fsInfo ->
fsInfo, nolMathLlwybr fsInfo
)
|> List.ofSeq
let nolHashFfeil enwLlawn =
use hasher = System.Security.Cryptography.SHA256.Create()
using (File.OpenRead enwLlawn) hasher.ComputeHash
let ynWahanol ewnLlawn1 math1 enwLlawn2 math2 =
match math1,math2 with
| Directory, Directory -> false
| File len1, File len2 when len1 = len2 ->
let hash1 = nolHashFfeil ewnLlawn1
let hash2 = nolHashFfeil enwLlawn2
hash1 = hash2
| _ -> true
let canlyniad =
[ "/tmp/1/", (nolFfeiliau "/tmp/1/") ; "/tmp/2/", (nolFfeiliau "/tmp/2/") ]
|> List.fold (fun coeden (llwybrCraidd,fsInfos) ->
fsInfos
|> List.fold (fun c (fsInfo, math) ->
let enwRelative = Path.GetRelativePath(llwybrCraidd, fsInfo.FullName)
let gwerth =
if Map.containsKey enwRelative c then c.[enwRelative] else Map.empty
|> Map.add llwybrCraidd math
if Map.containsKey enwRelative c then
Map.remove enwRelative c
else
c
|> Map.add enwRelative gwerth
) coeden
) Map.empty
canlyniad
|> Map.toList
|> List.sort
|> List.iter (fun (enwRelative, gwybodaeth) ->
if Map.count gwybodaeth = 1 then
let (fynhonell, math) = Map.toSeq gwybodaeth |> Seq.head
let enwLlawn = Path.Combine(fynhonell, enwRelative)
printfn "Dim ond %s yn bodoli, math: %A" enwLlawn math
if Map.count gwybodaeth = 2 then
let rhestr = Map.toArray gwybodaeth
let fynhonnel1, math1 = rhestr.[0]
let fynhonnel2, math2 = rhestr.[1]
let enwLlawn1 = Path.Combine(fynhonnel1, enwRelative)
let enwLlawn2 = Path.Combine(fynhonnel2, enwRelative)
if ynWahanol enwLlawn2 math1 enwLlawn2 math2 then
printfn "Mae %s (%A) yn wahanol i %s (%A)" enwLlawn1 math1 enwLlawn2 math2
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment