如何通过C#中指定的FileStream.Position和length获取字符串

时间:2018-05-29 09:41:38

标签: c#

我有一个函数,它在一个大型二进制文件中搜索字符串并将其位置给我。 如何实现一个读取该位置的函数,并在特定长度后给我字符串。 正如我们在 String.Substring()

中所做的那样

这是我到目前为止的代码。

public void example()
{

    string match = "400000002532"; //This is 12 chars in hex of the string to search
    byte[] matchBytes = StringToByteArray(match);


    foreach (var jsFile in jsscan)
    {
        using (var fs = new FileStream(jsFile, FileMode.Open))
        {
            int i = 0;
            int readByte;
            while ((readByte = fs.ReadByte()) != -1)
            {
                if (matchBytes[i] == readByte)
                {
                    i++;
                }
                else
                {
                    i = 0;
                }
                if (i == matchBytes.Length)
                {
                    Console.WriteLine("It found between {0} and {1}.", 
                       fs.Position - matchBytes.Length, fs.Position);
                    break;
                }
            }
       }
    }
}
public static byte[] StringToByteArray(String hex)
{
    int NumberChars = hex.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    return bytes;
 }

我正在搜索的示例如下

400000002532010953667A51E44BE5B6A59417B71F4B91BBE590B6AF6E84EF570C32C56400E05123B0A44AF389331E4B91B02E8980B85157F910D7238918A73012B6243F772F7B60E5A7CF6E8CB25374B8FF96311130AABD9F71A860C904C9F6AE9706E570CC0E881E997762710EDE8818CCC551BA05579D30C0D53CEBD9BAF0C2E557D7B9D37A9C94A8A9B5FA7FCF7973B0BDA88A06DE1AE357130E4A06018ABB0A1ABD818DABEB518649CF885953EE05564FD69F0E2F860175667C5FC84F1C97727CEA1C841BFA86A26BABA942E0275FAB2A8F78132E3A05404F0DCD02FD4E7CAD08B1FFD4C2184400F22F6EBC14857BCC2E2AF858BE20CBB807C3467A91E38F31901FD452B5F87F296174631980E039CAB58D97E8F91E3255DD7DEF3177D68A4943F629A70B421B1D6E53DC0D26A1B5EF7C6912F48E0842037FA72B17C18E11B93AEE4DDA0FFE6F217BD5DEB957B1C26169029DE4396103D1F89FA0856489B1958DE5C896DB8F27A24C21AC66BF2095E383DA5EC6DA7138FE82C62FDE9BEFF0308F507736F1B35B1CA083F6C96A6860889BDCCBC989E86F4FB1C483E71557369E7308450330AEF8C9A13A115E8A97642E4A0A4098F5BC04A096A22E5F97116B59AE17BCAEFD2A8B0BCB5341EC64CA3E474900D5A8A620448A6C97827C42332C4DD326572A3C5DB4DA1362F3C0012E1AA1B70C812DCCAEF74F67E94E907518CA31945DD56A61A7

2 个答案:

答案 0 :(得分:1)

如果表现不是很重要,您可以执行以下操作,这样更容易阅读

using (var fs = new StreamReader(fileName))
{
    var content = await fs.ReadToEndAsync();
    var pos = content.IndexOf(matchBytes);

    if (pos != -1)
    {
        Console.WriteLine($"Found @ {pos}, {pos + matchBytes.Length}");
    }
}

答案 1 :(得分:1)

假设您知道在Encoding中使用哪个Stream来存储字符,请尝试以下功能:

static string GetString(Stream stream, long position, int stringLength, Encoding encoding) {
    int offset = 0;
    int readByte;
    byte[] buffer = new byte[stream.Length - position];
    stream.Seek(position, SeekOrigin.Begin);
    while ((readByte = stream.ReadByte()) != -1)
    {
        buffer[offset++] = (byte)readByte;
        if (encoding.GetCharCount(buffer, 0, offset) == stringLength + 1)
        {                    
             return encoding.GetString(buffer, 0, offset - 1);
        }
    }
    if (encoding.GetCharCount(buffer, 0, offset) == stringLength)
    {
        return encoding.GetString(buffer, 0, offset);
    }
    throw new Exception(string.Format("Stream doesn't contains {0} characters", stringLength));
}

例如,使用您的代码和utf-16:

using (var fs = new FileStream(jsFile, FileMode.Open))
{
    int i = 0;
    int readByte;
    while ((readByte = fs.ReadByte()) != -1)
    {
        if (matchBytes[i] == readByte)
        {
            i++;
        }
        else
        {
            i = 0;
        }
        if (i == matchBytes.Length)
        {
            Console.WriteLine("It found between {0} and {1}.",
                        fs.Position - matchBytes.Length, fs.Position);

            //Desired string length in charachters
            const int DESIRED_STRING_LENGTH = 5;
            Console.WriteLine(GetString(fs, fs.Position, DESIRED_STRING_LENGTH, Encoding.Unicode));

            break;
        }
    }
}