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

发布于 2024-08-24 04:50:09 字数 3246 浏览 1 评论 0原文

我有一个 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。在计时器的 ElapsedEvent 侦听器中,我在下载目录中查找早于计时器间隔(对于测试 = 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 中以编程方式规避锁定的任何提示?客户端可能希望将应用程序发布到根目录。

I have a ASP.NET SOAP web service whose web method creates a PDF file, writes it to the "Download" directory of the applicaton, and returns the URL to the user. Code:

//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();
}

Then in the Global.asax file of the web service, I set up a Timer in the Application_Start event listener. In the Timer's ElapsedEvent listener I look for any files in the Download directory that are older than the Timer interval (for testing = 1 min., for deployment ~20 min.) and delete them. Code:

//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);
        }
    }
}

This works perfectly, with one exception. When I publish the web service application to inetpub\wwwroot (Windows 7, IIS7) it does not delete the old files in the Download directory. The app works perfect when I publish to IIS from a physical directory not in wwwroot. Obviously, it seems IIS places some sort of lock on files in the web root. I have tested impersonating an admin user to run the app and it still does not work. Any tips on how to circumvent the lock programmatically when in wwwroot? The client will probably want the app published to the root directory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

§普罗旺斯的薰衣草 2024-08-31 04:50:09

您的问题可能与以下事实有关:如果主文件夹中包含的目录或文件发生更改,IIS 会重新加载 Web 服务应用程序。

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

Your problem may be related to the fact that IIS reloads the Web Service Application if the directory or files contained in the main folder changes.

Try creating / deleting files in a temporary folder which is outside the root folder of your application (be aware of permissions on the folder to allow IIS to read/write files).

梦在深巷 2024-08-31 04:50:09

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

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

Instead of writing directly to the file system, why not use isolated storage?
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx

This should solve any location or permission based issues that you are having

爺獨霸怡葒院 2024-08-31 04:50:09

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

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

感谢所有回答的人。

I forgot to come back and answer my question.

I had to give the IIS_IUSRS group Modify permissions to the directory where I was reading/writing files.

Thanks to all those who answered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文