我收到了一个从磁盘读取内容的文件流。
foreach(DB::table('users')->paginate(2) as $object) {
echo $object->name;
}
此流将被传递到第三方库,该第三方库在读取流之后将Stream的位置指针保持在文件的末尾(作为用途)。
我的要求是不是每次都从桌面加载文件,而是我想保留A1,B1,A2,B2
,每次都会使用它。
object objCellText = Cells.GetType().InvokeMember("Item",
BindingFlags.GetProperty,null,Cells,
new object[] { RowIndex, ColIndex });
var CellText = objCellText.GetType().InvokeMember("Value",
BindingFlags.GetProperty, null, objCellText, null);
var CellName = objCellText.GetType().InvokeMember("Name",
BindingFlags.GetProperty, null, objCellText, null);
我试过上面的代码。它首次将输入流复制到输出流,但随后对Name
的调用将无法正常工作,因为源 Stream input = new FileStream("filename");
将位于流后的流的末尾。第一次打电话。
是否存在将源流的内容复制到另一个流的其他替代方案,而不管源流的当前MemoryStream
。
此代码需要在多线程环境中以线程安全的方式运行。
答案 0 :(得分:3)
您可以使用.NET 4.0 Stream.CopyTo将您的Steam复制到MemoryStream。 MemoryStream有一个Position属性,可用于将其帖子移动到开头。
var ms = new MemoryStream();
using (Stream file = File.OpenRead(@"filename"))
{
file.CopyTo(ms);
}
ms.Position = 0;
要创建一个线程安全的解决方案,您可以将内容复制到一个字节数组,并为需要访问的每个线程创建一个新的MemoryStream包装字节数组:
byte[] fileBytes = ms.ToArray();
var ms2 = new MemoryStream(fileBytes);
答案 1 :(得分:2)
您应该检查输入流的CanSeek
属性。如果返回false,则无论如何都只能读取它。如果CanSeek
返回true,则可以将位置设置为零并复制离开。
if (input.CanSeek)
{
input.Position = 0;
}
您可能还想存储旧位置并在复制后将其恢复。
ETA:传递Stream
周围的相同实例并不是最安全的事情。例如。当你找回Stream
时,你无法确定FileStream
是否被处理掉了。我建议在开头将MemoryStream
复制到ToArray()
,但只能通过调用Stream
来存储后者的字节内容。当您需要在某处传递new MemoryStream(byte[])
时,只需使用ID Department Category
555 16 test
888 16 test
0001 16 test
创建一个新的。{/ p>