我有一个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中以编程方式规避锁定的任何提示?客户端可能希望将应用程序发布到根目录。
答案 0 :(得分:4)
如果主文件夹中包含的一个或多个目录发生更改,IIS可能会重新加载Web服务应用程序。
尝试在应用程序根文件夹之外的临时文件夹中创建/删除文件(请注意该文件夹的权限以允许IIS读/写文件)。
答案 1 :(得分:1)
为什么不使用独立存储,而不是直接写入文件系统? http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx
这可以解决您遇到的任何基于位置或权限的问题
答案 2 :(得分:0)
我忘了回来回答我的问题。
我必须将 IIS_IUSRS 组修改权限授予我正在读取/写入文件的目录。
感谢所有回答的人。