FindFirstFileEx Function Searches a directory for a file or subdirectory with a name and attributes that match those specified.FindNextFile Function Continues a file search from a previous call to the FindFirstFile or FindFirstFileEx functionFindClose FunctionCloses a file search handle opened by the FindFirstFile, FindFirstFileEx, or FindFirstStreamW function
你这个问题微软已经意识到了,在.Net 4.0里已经用EnumerateFiles方法解决了。 不过仅就目前而言,也有办法,而且不需要使用Win32 API,而是用WMI 。 我不知道你是否使用过WMI,所以把方法也说给你: 添加引用:System.Management.dll 然后添加命名空间:using System.Management; 我给你写了两个方法: void CsToD1() { ManagementObjectSearcher mos = new ManagementObjectSearcher(@"select * from cim_datafile where drive='c:' and path='\\windows\\system32\\'"); int count = 0; //看起来返回的是集合,但是因为“延迟”特性,所以并没有枚举所有文件 foreach (ManagementBaseObject mbo in mos.Get()) { if (count++ == 20) break; Console.WriteLine(mbo["name"]); } } //如果你不懂延迟特性,请使用下面事件驱动的方式 void CsToD2() { ManagementObjectSearcher mos = new ManagementObjectSearcher(@"select * from cim_datafile where drive='c:' and path='\\windows\\system32\\'"); ManagementOperationObserver moo = new ManagementOperationObserver(); int count = 0; moo.ObjectReady += (obj, eve) => { if (count++ == 20) moo.Cancel(); ManagementBaseObject mbo = eve.NewObject; Console.WriteLine(mbo["name"]); }; mos.Get(moo); }
我写了个用API的例子: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices;namespace TestPInvoke { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); long size = 0; int files = 0; int folders = 0; WIN32_FIND_DATA findData; IntPtr findHandle; // please note that the following line won't work if you try this on a network folder, like \\Machine\C$ // simply remove the \\?\ part in this case or use \\?\UNC\ prefix findHandle = FindFirstFile(@"c:\*", out findData); if (findHandle != INVALID_HANDLE_VALUE) { do { if ((findData.dwFileAttributes & FileAttributes.Directory) == 0) { // File files++; Console.WriteLine(findData.cFileName + " " + findData.nFileSizeLow); } if (files == 50) break; } while (FindNextFile(findHandle, out findData)); FindClose(findHandle); } } public const int MAX_PATH = 260; public const int MAX_ALTERNATE = 14; [StructLayout(LayoutKind.Sequential)] public struct FILETIME { public uint dwLowDateTime; public uint dwHighDateTime; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WIN32_FIND_DATA { public FileAttributes dwFileAttributes; public FILETIME ftCreationTime; public FILETIME ftLastAccessTime; public FILETIME ftLastWriteTime; public int nFileSizeHigh; public int nFileSizeLow; public int dwReserved0; public int dwReserved1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] public string cFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ALTERNATE)] public string cAlternate; } [DllImport("kernel32", CharSet = CharSet.Unicode)] public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32", CharSet = CharSet.Unicode)] public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32", CharSet = CharSet.Unicode)] public static extern bool FindClose(IntPtr hFindFile); } }
或者按文件修改日期排序也行
如果不能排序的话,只要得到目录下任意50个文件也行
我的目的是不想用Directory.GetFiles()之类的方法把文件名全部取到一个数组里去,然后循环取
因为目录下的文件可能会比较多
不得到文件名又怎么排序呢?
Searches a directory for a file or subdirectory with a name and attributes that match those specified.FindNextFile Function
Continues a file search from a previous call to the FindFirstFile or FindFirstFileEx functionFindClose FunctionCloses a file search handle opened by the FindFirstFile, FindFirstFileEx, or FindFirstStreamW function
不过仅就目前而言,也有办法,而且不需要使用Win32 API,而是用WMI 。
我不知道你是否使用过WMI,所以把方法也说给你:
添加引用:System.Management.dll
然后添加命名空间:using System.Management;
我给你写了两个方法: void CsToD1()
{
ManagementObjectSearcher mos = new ManagementObjectSearcher(@"select * from cim_datafile where drive='c:' and path='\\windows\\system32\\'");
int count = 0;
//看起来返回的是集合,但是因为“延迟”特性,所以并没有枚举所有文件
foreach (ManagementBaseObject mbo in mos.Get())
{
if (count++ == 20)
break;
Console.WriteLine(mbo["name"]);
}
} //如果你不懂延迟特性,请使用下面事件驱动的方式
void CsToD2()
{
ManagementObjectSearcher mos = new ManagementObjectSearcher(@"select * from cim_datafile where drive='c:' and path='\\windows\\system32\\'");
ManagementOperationObserver moo = new ManagementOperationObserver();
int count = 0;
moo.ObjectReady += (obj, eve) =>
{
if (count++ == 20)
moo.Cancel();
ManagementBaseObject mbo = eve.NewObject;
Console.WriteLine(mbo["name"]);
};
mos.Get(moo);
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;namespace TestPInvoke
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{ IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
long size = 0;
int files = 0;
int folders = 0;
WIN32_FIND_DATA findData; IntPtr findHandle; // please note that the following line won't work if you try this on a network folder, like \\Machine\C$
// simply remove the \\?\ part in this case or use \\?\UNC\ prefix
findHandle = FindFirstFile(@"c:\*", out findData);
if (findHandle != INVALID_HANDLE_VALUE)
{
do
{
if ((findData.dwFileAttributes & FileAttributes.Directory) == 0)
{
// File
files++; Console.WriteLine(findData.cFileName + " " + findData.nFileSizeLow);
} if (files == 50)
break;
}
while (FindNextFile(findHandle, out findData));
FindClose(findHandle); } } public const int MAX_PATH = 260;
public const int MAX_ALTERNATE = 14; [StructLayout(LayoutKind.Sequential)]
public struct FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WIN32_FIND_DATA
{
public FileAttributes dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public int nFileSizeHigh;
public int nFileSizeLow;
public int dwReserved0;
public int dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ALTERNATE)]
public string cAlternate;
}
[DllImport("kernel32", CharSet = CharSet.Unicode)]
public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32", CharSet = CharSet.Unicode)]
public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32", CharSet = CharSet.Unicode)]
public static extern bool FindClose(IntPtr hFindFile); }
}
参考