2021-02-25 11:14:44 +01:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace MaddoShared
|
|
|
|
|
|
{
|
|
|
|
|
|
public class FileHelperOptions
|
|
|
|
|
|
{
|
|
|
|
|
|
public bool SeparateFiles { get; set; }
|
|
|
|
|
|
public NumerazioneType NumerationType { get; set; }
|
|
|
|
|
|
public int CounterSize { get; set; }
|
|
|
|
|
|
public string Suffix { get; set; }
|
|
|
|
|
|
public int FilesPerFolder { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
public enum NumerazioneType
|
|
|
|
|
|
{
|
|
|
|
|
|
Progressiva,
|
|
|
|
|
|
Files
|
|
|
|
|
|
}
|
|
|
|
|
|
public class FileHelperSharp
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
public List<FileData> GetFilesRecursive(DirectoryInfo root, DirectoryInfo destRoot, string filter, FileHelperOptions options)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConcurrentDictionary<FileInfo, DirectoryInfo> dirSourceDest = new ConcurrentDictionary<FileInfo, DirectoryInfo>();
|
|
|
|
|
|
List<FileInfo> result = new List<FileInfo>();
|
|
|
|
|
|
|
|
|
|
|
|
// Dim stack As New Stack(Of DirectoryInfo)
|
|
|
|
|
|
Stack<KeyValuePair<DirectoryInfo, DirectoryInfo>> stack = new Stack<KeyValuePair<DirectoryInfo, DirectoryInfo>>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KeyValuePair<DirectoryInfo, DirectoryInfo> pair = new KeyValuePair<DirectoryInfo, DirectoryInfo>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// stack.Push(root)
|
|
|
|
|
|
stack.Push(new KeyValuePair<DirectoryInfo, DirectoryInfo>(root, destRoot));
|
|
|
|
|
|
|
|
|
|
|
|
while ((stack.Count > 0))
|
|
|
|
|
|
{
|
|
|
|
|
|
KeyValuePair<DirectoryInfo, DirectoryInfo> curDirKV = stack.Pop();
|
|
|
|
|
|
// curDirKP = stack.Pop()
|
|
|
|
|
|
DirectoryInfo dir = curDirKV.Key;
|
|
|
|
|
|
DirectoryInfo dDir = curDirKV.Value;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// result.AddRange(dir.GetFiles(filter, SearchOption.TopDirectoryOnly))
|
|
|
|
|
|
// dividere file qui
|
|
|
|
|
|
if (options.FilesPerFolder > 0 & options.SeparateFiles)
|
|
|
|
|
|
AppendDictionaryConcurrent(dirSourceDest, DividiFilesInDirConcurrent(dir, dDir, options, filter));
|
|
|
|
|
|
else
|
|
|
|
|
|
AppendDictionaryConcurrent(dirSourceDest, DividiFilesInDirConcurrent(dir, dDir, options, filter));
|
|
|
|
|
|
|
|
|
|
|
|
foreach (DirectoryInfo subDirectory in dir.GetDirectories())
|
|
|
|
|
|
stack.Push(new KeyValuePair<DirectoryInfo, DirectoryInfo>(subDirectory, new DirectoryInfo(Path.Combine(dDir.FullName, subDirectory.Name))));
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO ERROR
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<FileData> resultData = new List<FileData>();
|
|
|
|
|
|
resultData.AddRange(from p in dirSourceDest
|
|
|
|
|
|
select new FileData(p.Key, p.Value));
|
|
|
|
|
|
return resultData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ConcurrentDictionary<FileInfo, DirectoryInfo> AppendDictionaryConcurrent(ConcurrentDictionary<FileInfo, DirectoryInfo> dictA, ConcurrentDictionary<FileInfo, DirectoryInfo> dictB)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (KeyValuePair<FileInfo, DirectoryInfo> pair in dictB)
|
|
|
|
|
|
dictA.TryAdd(pair.Key, pair.Value);
|
|
|
|
|
|
return dictA;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ConcurrentDictionary<FileInfo, DirectoryInfo> DividiFilesInDirConcurrent(DirectoryInfo dir, DirectoryInfo dirDest, FileHelperOptions options, string filter)
|
|
|
|
|
|
{
|
|
|
|
|
|
//int filesCount = dir.GetFiles(Filter).Length;
|
|
|
|
|
|
int contaFilePerDir = 0;
|
|
|
|
|
|
int contaDirPerDir = 0;
|
|
|
|
|
|
string tempText;// = string.Empty;
|
|
|
|
|
|
ConcurrentDictionary<FileInfo, DirectoryInfo> foldersDict = new ConcurrentDictionary<FileInfo, DirectoryInfo>();
|
|
|
|
|
|
|
|
|
|
|
|
DirectoryInfo destDir;
|
|
|
|
|
|
destDir = new DirectoryInfo(Path.Combine(dirDest.FullName));
|
2026-02-10 21:18:46 +01:00
|
|
|
|
|
|
|
|
|
|
// Support multiple patterns separated by ';' or ','
|
|
|
|
|
|
var patterns = (filter ?? "*").Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
// Collect matching files for all patterns and avoid duplicates
|
|
|
|
|
|
var matchedFiles = new List<FileInfo>();
|
|
|
|
|
|
foreach (var pat in patterns)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
matchedFiles.AddRange(dir.GetFiles(pat));
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
// Ignore pattern errors and continue
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Remove duplicates (by FullName)
|
|
|
|
|
|
var distinctFiles = matchedFiles.GroupBy(f => f.FullName, StringComparer.OrdinalIgnoreCase).Select(g => g.First()).OrderBy(f => f.Name).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (FileInfo file in distinctFiles)
|
2021-02-25 11:14:44 +01:00
|
|
|
|
{
|
|
|
|
|
|
contaFilePerDir += 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (contaFilePerDir == (contaDirPerDir * options.FilesPerFolder) + 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
contaDirPerDir += 1;
|
|
|
|
|
|
|
|
|
|
|
|
tempText = options.NumerationType == NumerazioneType.Progressiva ? contaDirPerDir.ToString() : (contaDirPerDir * options.FilesPerFolder).ToString();
|
|
|
|
|
|
int i;
|
|
|
|
|
|
for (i = 1; i <= (options.CounterSize - tempText.Length); i++)
|
|
|
|
|
|
tempText = "0" + tempText;
|
|
|
|
|
|
destDir = new DirectoryInfo(Path.Combine(dirDest.FullName, options.Suffix + tempText));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!destDir.Exists)
|
|
|
|
|
|
destDir.Create();
|
|
|
|
|
|
|
|
|
|
|
|
foldersDict.TryAdd(file, destDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return foldersDict;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|