C#尝试在使用MemoryStream类时替换一个字节

时间:2011-09-09 15:29:22

标签: c# memorystream

我从大型机获取文本文件,有时会在文本行的中间注入一些0x0D。

previos程序员使用FileStream类创建了一个方法。这种方法工作正常,但需要大约30分钟才能通过整个文件。

我的想法是将所需的文本行(大约25行)传递给方法,以减少处理时间。

我一直在使用MemoryStream类,但遇到问题时它找不到0x0D控制代码。

这是当前的FileStream方法:

private void ReplaceFileStream(string strInputFile)
{
    FileStream fileStream = new FileStream(strInputFile, FileMode.Open, FileAccess.ReadWrite);
    byte filebyte;

    while (fileStream.Position < fileStream.Length)
    {
        filebyte = (byte)fileStream.ReadByte();
        if (filebyte == 0x0D)
        {
            filebyte = 0x20;
            fileStream.Position = fileStream.Position - 1;
            fileStream.WriteByte(filebyte);
        }
    }
    fileStream.Close();
}

这是MemoryStream方法:

private void ReplaceMemoryStream(string strInputLine)
{
    byte[] byteArray = Encoding.ASCII.GetBytes(strInputLine);
    MemoryStream fileStream = new MemoryStream(byteArray);

    byte filebyte;

    while (fileStream.Position < fileStream.Length)
    {
        filebyte = (byte)fileStream.ReadByte();
        if (filebyte == 0x0D)
        {
            filebyte = 0x20;
            fileStream.Position = fileStream.Position - 1;
            fileStream.WriteByte(filebyte);
        }
    }
    fileStream.Close();
}

因为我之前没有使用过MemoryStream类,所以不熟悉它。任何提示或想法?

2 个答案:

答案 0 :(得分:3)

我不知道你文件的大小,但是如果它们足够小以至于你可以将整个内容一次加载到内存中,那么你可以这样做:

private void ReplaceFileStream(string strInputFile)
{
    byte[] fileBytes = File.ReadAllBytes(strInputFile);
    bool modified = false;
    for(int i=0; i < fileBytes.Length; ++i)
    {
        if (fileByte[i] == 0x0D)
        {
            fileBytes[i] = 0x20;
            modified = true;
        }
    } 

    if (modified)
    {
        File.WriteAllBytes(strInputFile, fileBytes);
    }
}

如果您无法立即读取整个文件,那么您应该切换到缓冲读取类型的设置,这里是一个从文件读取,写入临时文件,然后最终复制的示例临时文件超过原始文件。这应该会产生更好的性能,然后一次读取一个字节的文件:

private void ReplaceFileStream(string strInputFile)
{
    string tempFile = Path.GetTempFileName();
    try
    {
        using(FileStream input = new FileStream(strInputFile,
            FileMode.Open, FileAccess.Read))
        using(FileStream output = new FileStream(tempFile,
            FileMode.Create, FileAccess.Write))
       {
           byte[] buffer = new byte[4096];
           bytesRead = input.Read(buffer, 0, 4096);
           while(bytesRead > 0)
           {
                for(int i=0; i < bytesRead; ++i)
                {
                    if (buffer[i] == 0x0D)
                    {
                        buffer[i] = 0x20;
                    }
                }

                output.Write(buffer, 0, bytesRead);
                bytesRead = input.Read(buffer, 0, 4096);
            }
            output.Flush();
        }

        File.Copy(tempFile, strInputFile);
    }
    finally
    {
        if (File.Exists(tempFile))
        {
            File.Delete(tempFile);
        }
    }
}

答案 1 :(得分:2)

如果您的替换代码在流中找不到0x0D而前一个方法使用FileStream,我认为可能是因为您使用的编码来获取文件的字节,可以尝试其他一些编码类型。

否则你的代码看起来很好,我会在MemoryStream周围使用它来确保它被关闭和处理,如下所示:

using(var fileStream = new MemoryStream(byteArray))
{

  byte filebyte;

 // your while loop...

}

查看您的代码我不是100%确定您对内存流所做的更改将被保留;实际上我认为如果您在更改后没有保存它,您的更改将会丢失。我可能错了,但是你应该测试一下,如果没有保存,你应该使用StreamWriter在更改后保存它。