C# 在流中添加 40 个字节
Posted
技术标签:
【中文标题】C# 在流中添加 40 个字节【英文标题】:C# Prepend 40 bytes onto stream 【发布时间】:2013-12-13 10:51:44 【问题描述】:我正在尝试发送文件的 FileStream。
但我现在想在开头添加 40 字节的校验和。
我该怎么做?我尝试创建自己的流类来连接两个流。我还研究了流编写器。
当然,它们一定是一种简单的方法。或者另一种方式。而且我不想将整个文件加载到一个字节数组中,追加到那个并将它写回一个流中。
public Stream getFile(String basePath, String path)
return new FileStream(basePath + path, FileMode.Open, FileAccess.Read);
【问题讨论】:
【参考方案1】:见MergeStream.cs。使用方法如下:
var mergeStream = new MergeStream(new MemoryStream(checksum), File.OpenRead(path));
return mergeStream;
【讨论】:
这实际上和我之前所做的一样,只是我不知道如何处理缺少的抽象方法。又名NotSupportedException()
。谢谢:)
投掷NSE
对流很好。 MergeStream
是只读的,所以你可以在 Write
中做的唯一明智的方法是告诉调用者“嘿,我不支持写作!”【参考方案2】:
byte[] checksum = new byte[40];
//...
FileStream oldFileStream = new FileStream(oldFile, FileMode.Open, FileAccess.Read);
FileStream newFileStream = new FileStream(newFile, FileMode.Create, FileAccess.Write);
using(oldFileStream)
using(newFileStream)
newFileStream.Write(checksum, 0, checksum.Length);
oldFileStream.CopyTo(newFileStream);
File.Copy(newFile, oldFile, overwrite : true);
如果不想使用临时文件,唯一的解决办法就是以ReadWrite
模式打开文件并使用两个交替缓冲区:
private static void Swap<T>(ref T obj1, ref T obj2)
T tmp = obj1;
obj1 = obj2;
obj2 = tmp;
public static void PrependToFile(string filename, byte[] bytes)
FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite);
PrependToStream(stream, bytes);
public static void PrependToStream(Stream stream, byte[] bytes)
const int MAX_BUFFER_SIZE = 4096;
using(stream)
int bufferSize = Math.Max(MAX_BUFFER_SIZE, bytes.Length);
byte[] buffer1 = new byte[bufferSize];
byte[] buffer2 = new byte[bufferSize];
int readCount1;
int readCount2;
long totalLength = stream.Length + bytes.Length;
readCount1 = stream.Read(buffer1, 0, bytes.Length);
stream.Position = 0;
stream.Write(bytes, 0, bytes.Length);
int written = bytes.Length;
while (written < totalLength)
readCount2 = stream.Read(buffer2, 0, buffer2.Length);
stream.Position -= readCount2;
stream.Write(buffer1, 0, readCount1);
written += readCount1;
Swap(ref buffer1, ref buffer2);
Swap(ref readCount1, ref readCount2);
【讨论】:
@Doomsknight,是的,但它不会将整个文件加载到字节数组中,这是 OP 害怕的 =D @Sinatr 虽然我知道他避免了这种情况,但我不同意克隆 8GB 文件只是为了在前面添加 40 个字节是一个有效的解决方案。以上是关于C# 在流中添加 40 个字节的主要内容,如果未能解决你的问题,请参考以下文章