C# 在WCF中以原始格式返回后删除临时文件
我有一个WCF服务,它以原始格式工作,使用流:C# 在WCF中以原始格式返回后删除临时文件,c#,wcf,filestream,C#,Wcf,Filestream,我有一个WCF服务,它以原始格式工作,使用流: [ServiceContract] public interface IEncryptingService { [WebInvoke(UriTemplate = "/")] [OperationContract] Stream SignDocument(Stream requestStream); } public class EncryptingService : IEncryptingService { pub
[ServiceContract]
public interface IEncryptingService
{
[WebInvoke(UriTemplate = "/")]
[OperationContract]
Stream SignDocument(Stream requestStream);
}
public class EncryptingService : IEncryptingService
{
public Stream SignDocument(Stream requestStream)
{
string originalFileName = Path.GetTempFileName();
string signedFileName = Path.GetTempFileName();
using (var originalFileStream = File.Open(originalFileName, FileMode.Create, FileAccess.Write))
{
requestStream.CopyTo(originalFileStream);
}
XmlDocumentSigner.SignFile(originalFileName, signedFileName);
return File.Open(signedFileName, FileMode.Open, FileAccess.Read);
}
}
现在,在WCF结束返回该文件后,如何删除该文件
我尝试使用finally
块,但它在return
之后立即被调用,并抛出异常,因为该文件仍由进程使用
当然,这是一种解决方法,就像后台工作人员等待文件可供删除一样,但在我看来,这与web服务的实现方式不同。这个解决方案不可原谅地迅速浮现在脑海中,而且绝对合乎逻辑:我只需将文件内容读入内存并删除文件即可
public Stream SignDocument(Stream requestStream)
{
string originalFileName = Path.GetTempFileName();
string signedFileName = Path.GetTempFileName();
using (var originalFileStream = File.Open(originalFileName, FileMode.Create, FileAccess.Write))
{
requestStream.CopyTo(originalFileStream);
}
XmlDocumentSigner.SignFile(originalFileName, signedFileName);
byte[] signedFileBytes = File.ReadAllBytes(signedFileName);
File.Delete(signedFileName);
return new MemoryStream(signedFileBytes);
}
请注意,使用语句也会使此代码失败:
using (var ms = new MemoryStream(signedFileBytes))
{
return ms;
}
这个解决方案很快就出现在我的脑海中,这是完全合乎逻辑的:我可以简单地将文件内容读入内存并删除文件
public Stream SignDocument(Stream requestStream)
{
string originalFileName = Path.GetTempFileName();
string signedFileName = Path.GetTempFileName();
using (var originalFileStream = File.Open(originalFileName, FileMode.Create, FileAccess.Write))
{
requestStream.CopyTo(originalFileStream);
}
XmlDocumentSigner.SignFile(originalFileName, signedFileName);
byte[] signedFileBytes = File.ReadAllBytes(signedFileName);
File.Delete(signedFileName);
return new MemoryStream(signedFileBytes);
}
请注意,使用语句也会使此代码失败:
using (var ms = new MemoryStream(signedFileBytes))
{
return ms;
}
我还没有试过,但是你可以打开这个文件,把这个流写到另一个流。比如:
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(signedFileName))
{
//Read from fs and write to ms
}
然后,您只需对文件调用delete并返回ms
:
File.Delete(signedFileName);
return ms;
我还没有试过,但是你可以打开这个文件,把这个流写到另一个流。比如:
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(signedFileName))
{
//Read from fs and write to ms
}
然后,您只需对文件调用delete并返回ms
:
File.Delete(signedFileName);
return ms;
难道你一开始就不能避免使用文件吗?仅使用(内存中的)流?@Christian.K不幸的是,XmlDocumentSigner
是外部非托管DLL库的包装器,它使用非常特定的算法(无托管或非基于文件的替代库),并且只能对文件进行签名:(您不能首先避免使用文件吗?仅使用(内存中的)而是流?@Christian.K不幸的是,XmlDocumentSigner
是外部非托管DLL库的包装器,它使用非常特定的算法(无托管或非基于文件的替代库),并且只能对文件进行签名:(你打败了我,找到你的答案做得很好。你的答案也没那么复杂!@TheLethalCoder谢谢:)另请参见此处:。他们谈到了处理,但您可以订阅OperationCompleted并在此处删除您的文件。这比将整个文件复制到内存要好。您比我快,在找到您的答案方面做得很好。您的版本也不太复杂!@TheLethalCoder谢谢:)另请参见此处:。他们谈到处理,但您可以订阅OperationCompleted并在那里删除您的文件。这比将整个文件复制到内存要好。