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 个字节的主要内容,如果未能解决你的问题,请参考以下文章

Java字节流之ByteArrayInputStream

Cloud Firestore 在流中等待未来 - 使用用户 ID 将用户加入文档

防止在流中输入不需要的值

IO流

连接字节 [] 的 C# 列表

如何使用一种方法在网格 C# WPF 中添加行 [重复]