Пытаюсь скопировать (массив расширений файлов) в папку ( и в эту папку которую я копирую сделать ограничение в 100МБ), если лимит превышен файлов в папке, прекратить копировать! Вот код:
public static void GetFilesList()
{
long DS = 1000000;
string[] extens =
{
".txt", ".doc",
".cs", ".ico",
".Dll", ".Html",
".Htm", ".Xml",
".Php", ".png",
".jpg", ".gif"
};
if (DirSize(new DirectoryInfo(Easy.GooVer), DS) > DS)
{
foreach (string fileName in Directory.GetFiles(Easy.GooVer, "*.*", SearchOption.AllDirectories))
{
string ext = Path.GetExtension(fileName);
if (Array.IndexOf(extens, ext) >= 0)
{ try{
File.Copy(fileName, Path.Combine(Easy.str1, Path.GetFileName(fileName)), true);}catch { }
}
}
}
}
public static long DirSize(DirectoryInfo d, long aLimit = 0)
{
long Size = 0;
FileInfo[] fis = d.GetFiles();
foreach (FileInfo fi in fis)
{
Size += fi.Length;
if (aLimit > 0 && Size > aLimit)
return Size;
}
DirectoryInfo[] dis = d.GetDirectories();
foreach (DirectoryInfo di in dis)
{
Size += DirSize(di, aLimit);
if (aLimit > 0 && Size > aLimit)
return Size;
}
return (Size);
}
Попробуйте, например, так:
long copiedSoFar = 0;
foreach (string fileName in
Directory.GetFiles(Easy.GooVer, "*.*", SearchOption.AllDirectories))
{
string ext = Path.GetExtension(fileName);
if (Array.IndexOf(extens, ext) < 0)
continue;
try
{
var fileSize = new FileInfo(fileName).Length;
if (copiedSoFar + fileSize > DS)
continue; // другие файлы могут ещё влезть
File.Copy(fileName, Path.Combine(Easy.str1, Path.GetFileName(fileName)), true);
copiedSoFar += fileSize;
}
catch
{
// тут надо сделать что-то разумное
}
}
Можно эту задачу решить через паттерн ИТЕРАТОР, хотя может это будет и сложнее и больше писанины, но ведь это же классика!
Нам понадобиться Enumerator
internal class FilesEnumerator : IEnumerator<FileInfo>
{
private string _StartPath;
private IEnumerator<string> _FileEnumerator;
//ctor
public FilesEnumerator(string startPath, string searchPattern)
{
_StartPath = startPath;
var files = Directory.EnumerateFiles(_StartPath, searchPattern, SearchOption.AllDirectories);
_FileEnumerator = files.GetEnumerator();
}
public FileInfo Current
{
get
{
return new FileInfo(_FileEnumerator.Current);
}
}
object IEnumerator.Current
{
get
{
return this.Current;
}
}
public bool MoveNext()
{
return _FileEnumerator.MoveNext();
}
public void Reset()
{
_FileEnumerator.Reset();
}
public void Dispose()
{
_FileEnumerator.Dispose();
}
}
далее локатор
public class FilesLocator : IEnumerable<FileInfo>
{
private string _StartPath;
private string _SearchPattern;
//ctor
public FilesLocator(string startPath, string searchPattern = "*.*")
{
if (String.IsNullOrEmpty(startPath)) throw new ArgumentException($"{nameof(startPath)} не может быть пустым");
if (String.IsNullOrEmpty(startPath)) throw new ArgumentException($"{nameof(searchPattern)} не может быть пустым");
_StartPath = startPath;
_SearchPattern = searchPattern;
}
public IEnumerator<FileInfo> GetEnumerator()
{
return new FilesEnumerator(_StartPath, _SearchPattern);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Ну, а пользоваться можно так
[TestMethod()]
public void FilesLocatorTest()
{
string fromC = @"D:\Temp";
string toC = @"C:\Temp";
//вы уж извините, я тут свои другие расширения подставил
List<string> extensions = new List<string>() { ".json", ".txt" };
//опять же можете др. лимит прописать
long limit = 100000;
var files = new FilesLocator(fromC);
foreach (var file in files)
{
string ext = Path.GetExtension(file.Name);
int id = extensions.IndexOf(ext);
if ( id < 0) continue;
if ((limit -= file.Length) < 0) break;
try
{
file.CopyTo(Path.Combine(toC, file.Name));
}
catch
{
//
}
}
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Краткий, может быть глупый вопрос: как при создании List<тип> выделить сразу память под n Элементов? Конструктор позволяет задать только примерную...