C# 在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

我有一个WCF服务,它以原始格式工作,使用流:

[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并在那里删除您的文件。这比将整个文件复制到内存要好。