【问题标题】:Remove null bytes from the beginning of a stream从流的开头删除空字节
【发布时间】:2012-03-18 00:25:37
【问题描述】:

我在 dll 中有一个类,它解析文件并返回代表 FAT 图像(或任何 其他)的 Stream

我的问题是当有任何 other 图像时,该类在流的开头创建大约 3702(平均)空字节。

所以我必须先编辑流,然后将其保存到文件中。

我已经有一个代码,但运行缓慢。

[注意:fts 是返回的 FileStream。]

BufferedStream bfs = new BufferedStream(fts);
BinaryReader bbr = new BinaryReader(bfs);
byte[] all_bytes = bbr.ReadBytes((int)fts.Length);

List<byte> nls = new List<byte>();
int index = 0;

foreach (byte bbrs in all_bytes)
{
    if (bbrs == 0x00)
    {
        index++;
        nls.Add(bbrs);
    }
    else
    {
        break;
    }
}

byte[] nulls = new byte[nls.Count];
nulls = nls.ToArray();

//File.WriteAllBytes(outputDir + "Nulls.bin", nulls);
long siz = fts.Length - index;
byte[] file = new byte[siz];

bbr.BaseStream.Position = index;
file = bbr.ReadBytes((int)siz);

bbr.Close();
bfs.Close();
fts.Close();

bfs = null;
fts = null;

fts = new FileStream(outputDir + "Image.bin", FileMode.Create, FileAccess.Write);
bfs = new BufferedStream(fts);

bfs.Write(file, 0, (int)siz);

bfs.Close();
fts.Close();

现在,我的问题是:

我怎样才能比上面的代码更有效、更快地删除空值?

【问题讨论】:

    标签: c# stream null


    【解决方案1】:

    您可以简单地循环遍历流,直到找到第一个非空字节,然后使用 Array.Copy 从那里复制数组,而不是将字节推送到列表中。

    我会考虑这样的事情(未经测试的代码):

    int index = 0;
    int currByte = 0;
    
    while ((currByte = bbrs.ReadByte()) == 0x00)
    {
        index++;
    }
    
    // now currByte and everything to the end of the stream are the bytes you want.
    

    【讨论】:

    • 为什么要使用 currByte?我没有注意到任何区别。肯定会节省一些时间....
    • @WritZ:您要保存 currByte,因为当 while 循环退出时,它将包含您需要保存的第一个字节。否则,您将丢失第一个字节(除非您将流向后移动一个字节)。再次查看 BinaryReader,您还可以使用 PeekChar 以便在您的 while 条件下不推进流(但请记住在循环体中推进它!)
    • 不需要!图像大小 = fts.Length - 索引。 AllBytes 是整个 Stream 然后使用 Array.Copy 复制索引后的字节。我已经这样做了...
    • @Writz:很公平。在我看来,我不会先将所有字节读入数组,但这是一个相当小的优化。
    最近更新 更多