将流传递给多个方法可以吗?

时间:2012-02-28 20:32:19

标签: c#

我的界面定义为:

public interface IClientFileImporter
{
    bool CanImport(Stream stream);
    int Import(Stream stream);
}

这个想法是获取任何文件流并通过该接口的一系列实现来运行它,以确定哪个文件流应该处理该文件。一些实现可能会查找某个标题行,而其他实现可能会查找某个字节序列等...

我的问题是,只要我从不关闭它就可以像这样传递流吗?如有必要,每种方法都必须负责将流重置到位置0,但是还有其他潜在的问题(除了线程安全)吗?这段代码真的很有气味,IMO,但我不确定是否有更好的方法。

5 个答案:

答案 0 :(得分:3)

要防止修改基础流,请创建一个从Stream派生的包装流,并仅转发对包装流的安全调用。此外,不要假设Import / CanImport方法重置流位置。这些方法的调用者应该在将流传递给Import / CanImport之前将流重置为有效状态。

答案 1 :(得分:2)

如果每个函数都以它获得它的方式返回流,我认为它没有问题。

答案 2 :(得分:2)

这应该不是问题。

虽然我可能会稍微重组一下:

public interface IClientFileImporter
{
    int Import(Stream stream);
}

然后我会让Import方法返回-1,如果它不能。可能会使您的其他代码更简单。

答案 3 :(得分:0)

将相同的流传递给多个方法完全没问题。

注意不可搜索的流 - 有些流无法重置位置。 Andre Loker的评论有很好的建议来包装Stream,所以CanImport方法不会弄乱实际的流。

您还可以考虑向CanImport方法明确提供流的一些“标题”部分,也会降低它们的灵活性。

答案 4 :(得分:0)

如果您担心传递流,因为您最终可能会运行可能不值得信任的外部代码,那么您可以做的最好的事情是创建一个新的只读流并传递它,以便不会更改外部代码文件的内容,直到您确定要让它们为止。

public class ReadonlyStream : Stream
{
    public ReadonlyStream(Stream baseStream)
    {
        ownerStream = baseStream;
    }

    private Stream ownerStream;

    public override bool CanWrite
    {
        get { return false; }
    }

    public override int Write(byte[] bits, int offset, int count)
    {
        throw new InvalidOperationException();
    }

    // Other code ommitted
}