为啥有这个话题,小编最近有个下载数据量的报表需求,实现原理是新开一个线程,用这个线程去按照分页的方式整合数据,整合完成后生成Excel文件,前台会有个方法来定时扫描这个文件,如果文件存在导出。功能实现了,但是在下载数据量大的情况报错了,明明找到了文件下载不下来,翻阅了一下错误原因,原来文件太大了,生成文件太慢导致文件是占用状态。怎么解决,在判断文件是否存在的情况下再判断一下是否被占用,有两种方法,如下:.
一、WIN32 API调用
[DllImport("kernel32.dll")]
public static extern IntPtr _lopen(string lpPathName, int iReadWrite);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
public const int OF_READWRITE = 2;
public const int OF_SHARE_DENY_NONE = 0x40;
public static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
public static bool IsOccupied(string fileFullNmae)
{
if (!File.Exists(fileFullNmae)) return false;
IntPtr vHandle = _lopen(fileFullNmae, OF_READWRITE | OF_SHARE_DENY_NONE);
var flag = vHandle == HFILE_ERROR;
CloseHandle(vHandle);
return flag;
}
static void Main()
{
string pathname = "d:\\Temp\\test.xlsx";
var rel = IsOccupied(pathname);
}//rel结果如果占用为true,否则为false
二、通过文件流方式打开测试
//判断文件是否占用
public static bool IsFileInUse(string fileName)
{
bool inUse = true;
FileStream fs = null;
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read,
FileShare.None);
inUse = false;
}
catch
{
}
finally
{
if (fs != null)
fs.Close();
}
return inUse;//true表示正在使用,false没有使用
}
//调用
static void Main()
{
string pathname = "d:\\Temp\\test.xlsx";
var rel = IsFileInUse(pathname);
}//rel结果如果占用为true,否则为false
结语
这两种方法推荐使用第二种方法,第一种方法如果跨平台可能会有问题。网上还有其他方法,比如执行copy文件等,从实用性还是觉得这两种方法比较好。