Производительная копия файла в C#?

попробуйте это:

PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out))
7
задан Scott Klarenbach 4 November 2009 в 22:49
поделиться

6 ответов

The only part that I think you could improve is the dirInfo.GetFiles("*.*"). In .NET 3.5 and earlier, it returns an array with all the file names, which takes time to build and uses lots of RAM. In .NET 4.0, there is a new Directory.EnumerateFiles method that returns an IEnumerable instead, and fetches results immediately as they are read from the disk. This could improve performance a bit, but don't expect miracles...

10
ответ дан 6 December 2019 в 10:51
поделиться

You should consider using a third party utility to perform the copying for you. Something like robocopy may speed up your processing significantly. See also https://serverfault.com/questions/54881/quickest-way-of-moving-a-large-number-of-files

2
ответ дан 6 December 2019 в 10:51
поделиться

I'd keep in mind the 80/20 rule and note that if the bulk of the slowdown is file.CopyTo, and this slowdown far outweighs the performance of the LINQ query, then I wouldn't worry. You can test this by removing the file.CopyTo line and replacing it with a Console.WriteLine operation. Time that versus the real copy. You'll find the overhead of GoGrid versus the rest of the operation. My hunch is there won't be any realistic big gains on your end.

EDIT: Ok, so the 80% is the GetFiles operation, which isn't surprising if in fact there are a million files in the directory. Your best bet may be to begin using the Win32 API directly (like FindFirstFile and family) and P/Invoke:

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
static extern IntPtr FindFirstFile(string lpFileName, 
    out WIN32_FIND_DATA lpFindFileData);

I'd also suggest, if possible, altering the directory structure to decrease the number of files per directory. This will improve the situation immensely.

EDIT2: I'd also consider changing from GetFiles("*.*") to just GetFiles(). Since you're asking for everything, no sense in having it apply globbing rules at each step.

2
ответ дан 6 December 2019 в 10:51
поделиться

Вы можете поэкспериментировать с использованием (ограниченного числа) потоков для выполнения CopyTo (). Сейчас вся операция ограничена одним ядром.

Это улучшит производительность, только если теперь она привязана к ЦП. Но если это работает на RAID, это может сработать.

1
ответ дан 6 December 2019 в 10:51
поделиться

Послушайте этот подкаст Hanselminutes . Скотт разговаривает с Аароном Боковером, автором медиаплеера Banshee, они столкнулись с этой конкретной проблемой и рассказали об этом в 8:20 в подкасте.

Если вы можете использовать .Net 4.0, используйте их Directory.EnumerateFiles, как указано в Томас Левеск. В противном случае вам может потребоваться написать собственный код обхода каталогов, как это было в Mono.Posix, с использованием собственных API Win32.

0
ответ дан 6 December 2019 в 10:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: