简体   繁体   English

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

[英]C# Trying to replace a byte while using MemoryStream class

I get a text file from a mainframe and sometimes there are some 0x0D injected into the middle of the text lines. 我从大型机获取文本文件,有时在文本行的中间注入了一些0x0D。

The previos programmer created a method using the FileStream class. previos程序员使用FileStream类创建了一个方法。 This method works fine but is taking around 30 minutes to go thru the entire file. 这种方法工作正常,但需要大约30分钟才能通过整个文件。

My thought was to pass the text lines that are needed (about 25 lines) to a method to decrease the processing time. 我的想法是将所需的文本行(大约25行)传递给方法以减少处理时间。

I've been working with the MemoryStream class but am having issue where it does not find the 0x0D control code. 我一直在使用MemoryStream类,但遇到问题,它没有找到0x0D控制代码。

Here is the current FileStream method: 这是当前的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();
}

and here is the MemoryStream method: 这是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();
}

As I have not used the MemoryStream class before am not that familar with it. 因为我之前没有使用过MemoryStream类,所以不熟悉它。 Any tips or ideas? 任何提示或想法?

I don't know the size of your files, but if they are small enough that you can load the whole thing in memory at once, then you could do something like this: 我不知道你的文件的大小,但如果它们足够小,你可以一次加载整个内存,那么你可以做这样的事情:

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);
    }
}

If you can't read the whole file in at once, then you should switch to a buffered reading type of setup, here is an example that reads from the file, writes to a temp file, then in the end copies the temp file over the original file. 如果您无法立即读取整个文件,那么您应该切换到缓冲读取类型的设置,这是一个从文件读取,写入临时文件,然后最终复制临时文件的示例原始文件。 This should yield better performance then reading a file one byte at a time: 这应该会产生更好的性能,然后一次读取一个字节的文件:

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);
        }
    }
}

if your replacement code does not find the 0x0D in the stream and the previous method with the FileStream does it, I think it could be because of the Encoding you are using to get the bytes of the file, you can try with some other encoding types. 如果您的替换代码没有在流中找到0x0D ,并且使用FileStream的前一个方法执行此操作,我认为可能是因为您使用的编码来获取文件的字节,您可以尝试使用其他一些编码类型。

otherwise your code seems to be fine, I would use a using around the MemoryStream to be sure it gets closed and disposed, something like this: 否则你的代码似乎很好,我会在MemoryStream周围使用它来确保它被关闭和处理,如下所示:

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

  byte filebyte;

 // your while loop...

}

looking at your code I am not 100% sure the changes you make to the memory stream will be persisted; 查看您的代码我不是100%确定您对内存流所做的更改将被保留; Actually I think that if you do not save it after the changes, your changes will be lost. 实际上我认为如果您在更改后没有保存它,您的更改将会丢失。 I can be wrong in this but you should test and see, if it does not save you should use StreamWriter to save it after the changes. 我可能在这方面是错的,但你应该测试并看看,如果不能保存,你应该使用StreamWriter在更改后保存它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM