我的界面定义为:
public interface IClientFileImporter
{
bool CanImport(Stream stream);
int Import(Stream stream);
}
这个想法是获取任何文件流并通过该接口的一系列实现来运行它,以确定哪个文件流应该处理该文件。一些实现可能会查找某个标题行,而其他实现可能会查找某个字节序列等...
我的问题是,只要我从不关闭它就可以像这样传递流吗?如有必要,每种方法都必须负责将流重置到位置0,但是还有其他潜在的问题(除了线程安全)吗?这段代码真的很有气味,IMO,但我不确定是否有更好的方法。
答案 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
}