C# 如何通过FileStream获取字符串。c中指定的位置和长度#

C# 如何通过FileStream获取字符串。c中指定的位置和长度#,c#,C#,我有一个函数,它在一个大的二进制文件中搜索字符串并给我它的位置。 如何实现读取该位置并在指定长度后给我字符串的函数。 正如我们在String.Substring()中所做的那样 这是我到目前为止的代码 public void example() { string match = "400000002532"; //This is 12 chars in hex of the string to search byte[] matchBytes = StringToByteArr

我有一个函数,它在一个大的二进制文件中搜索字符串并给我它的位置。 如何实现读取该位置并在指定长度后给我字符串的函数。 正如我们在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;
 }

如果性能不是很大的问题,您可以执行以下操作,这更容易理解

使用(var fs=newstreamreader(文件名))
{
var content=wait fs.ReadToEndAsync();
var pos=content.IndexOf(匹配字节);
如果(位置!=-1)
{
WriteLine($“Found@{pos},{pos+matchBytes.Length}”);
}
}

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

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

因此,您不想知道如何获取位置,您只想知道如何将目标字符串后面的一定数量的字节转换为字符串?如果是这样的话,你怎么知道下面的字符串中应该有多少个字符呢?假设你有utf-16编码的字节,知道开始索引和字节计数,那么用Encoding.Unicode.GetString(bytes,start,count)@IgorBendrup从字节数组中提取子字符串并不像你想象的那么简单,由于每个字符(UTF16中)或每个字符(UTF8中)可能不正好有两个字节因为某些字符可能被编码为三个或更多字节。@MatthewWatson我有一系列十六进制,我想搜索,就像第一个十六进制字符串的长度为1040个字符,其他两个十六进制字符串的长度为512个字符一样。@MatthewWatson,如果OP知道要转换为字符串的字节(而不是字符)的确切计数,那就没有意义了。如果OP不知道字节数,但只知道字符数,他可以反复使用Encoding.GetCharCount(bytes,start,byteCount)来获得正确的字节数我的意思是我想要的数据在哪里?它只给了这个职位!这件事变得非常棘手,因为我不知道编码。@AmanAli编码检测是非常不同的任务。退房但最好向文件的作者询问所使用的编码。遗憾的是,作者不为人知。
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;
        }
    }
}