问题
This question provides a fast way to use the kernel.dll
to recursively find file attributes, e.g. file names. The problem is reporting progress (such as in a Windows Forms App) is limited to which file or directory it is currently on as it has no information as to total file count upfront.
Though, I know in Windows 7 if you use the file explorer to search for a file, it shows a progress bar for the search:

So how is it they do it here? Is total file count known here ahead of time? Is it possible to mimic this kind of progress reporting in the answer from the question linked above? I'm not sure how to do it without a total file count upfront.
The closest question I could find was this one which seems to have some problems with this recursion method as I don't have folder count upfront, and the behavior would be very odd for a single directory of many files.
回答1:
Depending on how accurate you need to get, there may be a simple two-pass solution (not optimal for network drives, so you may need to tune there).
For the first n
levels of directories (say 4, including drive), count the number of sub-directories. This is typically a quick operation, although you can tweak it to only recurse when more than say 5 subdirectories are present or similar. Store this number.
As you perform the real search, keep track of the number of subdirectories you've completed that are within n
steps of the root. Use this number and the stored count to estimate completion.
For example, with the basic structure:
C:\
a\
1\
i\
ii\
iii\
2\
3\
b\
c\
Count a, 1, ignore i and siblings, count 2, etc. Then, while searching, increase the bar when you finish searching 3, 2, 1, a, etc.
Now, this is absolutely not fool-proof. There may be race conditions, it's not terribly accurate, and all sorts of other things.
However, for a low-granularity progress bar, it's close enough that it will appear pretty accurate. More importantly from a user-experience perspective, using a stored count and comparing progress against that tends to prevent the bar from growing halfway through the process.
I'm actually using this technique in some code here.
The initial build, which goes down 10 levels, is still pretty speedy. I don't remember just how much testing went into it, but the bar is visibly accurate without many pauses when searching through 2.5-3 million files (despite only checking 1/1000th of that ahead of time). Note that the shorter your progress bar, the more accurate it will appear. ;)
回答2:
Start a thread in the background that counts the files under the directory you are searching. In the background, update the number of files counted so far. Use this count in your progress bar. Once this count is greater than one, it is safe to start the search. When computing progress, fudge the result if your search (miraculously) outpaces your background file counter, or if an occaional visible digression in the progress bar is unacceptable.
This then leaves figuring out the fastest way to count files (consider FindFirstFileEx). On a local drive, it might might take 2 or 3 seconds to count a folder like Program Files. Over the network, it will take a lot longer because with FindFirstFileEx, file names are transmitted when you only want the count of files and a list of directories.
This all presumes you will spend a lot more time in the search than in just counting files.
来源:https://stackoverflow.com/questions/12042159/updating-progress-bar-during-a-file-search