我有一个基于字符串列表处理文件流的应用程序,该字符串可以是磁盘上的文件,也可以是Zip文件中的文件。为了清理代码,我想重构打开文件的过程。

我创建了一个返回文件内容流的方法,但是由于该流取决于ZipFile IDisposable,因此当我读取该流时,ZipFile会抛出异常。

void Main()
{
    using (var stream = OpenFileForImport("zipfile.zip;insidefile.txt"))
        new StreamReader(stream).ReadToEnd(); // Exception

    using (var stream = OpenFileForImport("outside.txt"))
        new StreamReader(stream).ReadToEnd(); // Works
}
public static Stream OpenFileForImport(string filePath)
{
    var path = Path.Combine(basefolder, filePath);

    if (path.Contains(";"))
    {
        var parts = path.Split(';');
        var zipPath = parts[0];

        //Error checking logic to ensure zip file exists and is valid...
        using (var zip = ZipFile.OpenRead(zipPath))
        using (var entry = zip.GetEntry(parts[1]))
        {
            //Error checking logic to ensure inside file exists within zip file.
            return entry.Open();
        }

    }

    var file = new FileInfo(path);
    if (file != null)
        return file.OpenRead();

    return null;

}


我可以从zipentry声明中删除using子句,但是我怀疑它们是否会被废弃。当依靠其他一次性用品时,是否有适当的方式退还一次性用品?

最佳答案

不要直接返回该流,而是返回一个可以提供要处置的流的可抛弃对象,但是当处置该流和其他相关资源时,该对象将被清除:

public class NameToBeDetermined : IDisposable
{
    private ZipFile zip;
    public Stream Stream { get; }
    public NameToBeDetermined(ZipFile zip, Stream stream)
    {
        this.zip = zip;
        Stream = stream;
    }
    public void Dispose()
    {
        zip.Dispose();
        Stream.Dispose();
    }
}


然后返回该值,而不是返回流本身。如果值得花时间,可以将包装器本身转换为Stream,将所有Stream方法转发到组合流中,但是在处理时会做额外的工作。是否值得花时间创建更多涉及的包装器,而不是让调用者访问Stream属性。

关于c# - 取决于其他一次性用品的一次性用品,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48214328/

10-10 09:28