ASP.NET-使用System.IO.File.Delete()从wwwroot中的目录中删除文件?

时间:2010-03-05 16:17:57

标签: asp.net web-services iis-7 file-io asmx

我有一个ASP.NET SOAP Web服务,其Web方法创建一个PDF文件,将其写入应用程序的“下载”目录,并将URL返回给用户。代码:

//Create the map images (MapPrinter) and insert them on the PDF (PagePrinter).
MemoryStream mstream = null;
FileStream fs = null;
try
{
    //Create the memorystream storing the pdf created.
    mstream = pgPrinter.GenerateMapImage();
    //Convert the memorystream to an array of bytes.
    byte[] byteArray = mstream.ToArray();
    //return byteArray;

    //Save PDF file to site's Download folder with a unique name.
    System.Text.StringBuilder sb = new System.Text.StringBuilder(Global.PhysicalDownloadPath);
    sb.Append("\\");
    string fileName = Guid.NewGuid().ToString() + ".pdf";
    sb.Append(fileName);
    string filePath = sb.ToString();
    fs = new FileStream(filePath, FileMode.CreateNew);
    fs.Write(byteArray, 0, byteArray.Length);
    string requestURI = this.Context.Request.Url.AbsoluteUri;
    string virtPath = requestURI.Remove(requestURI.IndexOf("Service.asmx")) + "Download/" + fileName;
    return virtPath;
}
catch (Exception ex)
{
    throw new Exception("An error has occurred creating the map pdf.", ex);
}
finally
{
    if (mstream != null) mstream.Close();
    if (fs != null) fs.Close();
    //Clean up resources
    if (pgPrinter != null) pgPrinter.Dispose();
}

然后在Web服务的Global.asax文件中,我在Application_Start事件侦听器中设置了一个Timer。在Timer的ElapsedEvent监听器中,我查找Download目录中早于Timer间隔的任何文件(测试= 1分钟,部署~20分钟)并删除它们。代码:

//Interval to check for old files (milliseconds), also set to delete files older than now minus this interval.
private static double deleteTimeInterval;
private static System.Timers.Timer timer;
//Physical path to Download folder.  Everything in this folder will be checked for deletion.
public static string PhysicalDownloadPath;

void Application_Start(object sender, EventArgs e)
{
    // Code that runs on application startup
    deleteTimeInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["FileDeleteInterval"]);
    //Create timer with interval (milliseconds) whose elapse event will trigger the delete of old files
    //in the Download directory.
    timer = new System.Timers.Timer(deleteTimeInterval);
    timer.Enabled = true;
    timer.AutoReset = true;
    timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);

    PhysicalDownloadPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Download";
}

private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
    //Delete the files older than the time interval in the Download folder.
    var folder = new System.IO.DirectoryInfo(PhysicalDownloadPath);
    System.IO.FileInfo[] files = folder.GetFiles();
    foreach (var file in files)
    {
        if (file.CreationTime < DateTime.Now.AddMilliseconds(-deleteTimeInterval))
        {
            string path = PhysicalDownloadPath + "\\" + file.Name;
            System.IO.File.Delete(path);
        }
    }
}

这完美无缺,但有一个例外。当我将Web服务应用程序发布到inetpub \ wwwroot(Windows 7,IIS7)时,它不会删除下载目录中的旧文件。当我从不在wwwroot中的物理目录发布到IIS时,该应用程序工作正常。显然,似乎IIS对Web根目录中的文件设置了某种锁定。我已经测试过冒充管理员用户来运行应用程序,但它仍然无效。有关如何在wwwroot中以编程方式规避锁定的任何提示?客户端可能希望将应用程序发布到根目录。

3 个答案:

答案 0 :(得分:4)

如果主文件夹中包含的一个或多个目录发生更改,IIS可能会重新加载Web服务应用程序。

尝试在应用程序根文件夹之外的临时文件夹中创建/删除文件(请注意该文件夹的权限以允许IIS读/写文件)。

答案 1 :(得分:1)

为什么不使用独立存储,而不是直接写入文件系统? http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx

这可以解决您遇到的任何基于位置或权限的问题

答案 2 :(得分:0)

我忘了回来回答我的问题。

我必须将 IIS_IUSRS 修改权限授予我正在读取/写入文件的目录。

感谢所有回答的人。