简体   繁体   English

在文件中查找特定值

[英]Finding a specific value in a file

I am trying to make a simple program to find some values in a file. 我正在尝试创建一个简单的程序来查找文件中的某些值。 These files are .arkprofile files and belong to the game ARK . 这些文件是.arkprofile文件,属于游戏ARK

These .arkprofile files include some readable text as well as some scrambled text if you open it in a regular editor. 这些.arkprofile文件包含一些可读文本以及一些加扰文本(如果您在常规编辑器中打开它)。 All the values I need are in ASCII so I could get them all manually, but the intention of this program is to go through a lot of files to grab out the character names. 我需要的所有值都是ASCII,所以我可以手动获取它们,但是这个程序的目的是通过大量文件来获取字符名称。 Here is how it looks like in the file in a regular text editor: 以下是常规文本编辑器中文件的外观:

PlayerCharacterName.....StrProperty.............CHARACTERNAMEHERE

Can I find this string without decompiling the file as hex first? 我可以找到这个字符串而不首先将文件反编译为十六进制吗? Is it possible to convert the string to bytes and do the search from there? 是否可以将字符串转换为字节并从那里进行搜索?

This is the code I have at the moment, but it is not suited for my need as the hex offset for the string is not the same for all the files. 这是我目前的代码,但它不适合我的需要,因为字符串的十六进制偏移量对于所有文件都不相同。

Dim pos1 As Long = 864

Dim requiredBytes As Integer = 160
Dim value(0 To requiredBytes - 1) As Byte
Using reader As New BinaryReader(File.Open(fd.FileName, FileMode.Open))
    ' Loop through length of file.
    Dim fileLength As Long = reader.BaseStream.Length
    Dim byteCount As Integer = 0
    reader.BaseStream.Seek(pos1, SeekOrigin.Begin)
    While pos1 < fileLength And byteCount < requiredBytes
        value(byteCount) = reader.ReadByte()
        pos1 += 1
        byteCount += 1
    End While
End Using

The dots between the strings change hex value from file to file, but its always the same amount of dots. 字符串之间的点会在文件之间更改十六进制值,但它始终具有相同的点数。 Max character name allowed on ARK is 24, so my idea now was to first find that string in the file, start writing bytes from the end of that file for 128 bytes. ARK上允许的最大字符名称是24,所以我现在的想法是首先在文件中找到该字符串,开始从该文件的末尾写入128字节的字节。 "PlayerCharacterName.....StrProperty............." = 60 bytes. “PlayerCharacterName ..... StrProperty .............”= 60个字节。 This is where the username would start and can be up to 24 characters long which is 48 bytes. 这是用户名将开始的位置,最长可达24个字符,即48个字节。 Then I could filter out the remaining characters that are not a part of the username and display it in ASCII. 然后我可以过滤掉不属于用户名的剩余字符并以ASCII格式显示。

Am I way off track here? 我在这里偏离轨道吗?

Since you can read it in a text editor, you can just open it as a text file. 由于您可以在文本编辑器中阅读它,因此您只需将其作为文本文件打开即可。

Imports System.IO

Module Module1

    Sub Main()
        Dim line As String = ""
        Using sr As New StreamReader("c:\temp\test.abc")
            While Not sr.EndOfStream
                line = sr.ReadLine()
                If line.StartsWith("PlayerCharacterName") Then
                    Exit While
                End If
            End While
        End Using
        If line = "" Then
            Console.WriteLine("Did not find the name!")
        Else
            Dim s = line.Split("."c)
            Dim name = s.Last()
            Console.WriteLine("Found name ""{0}""", name)
        End If
        Console.Read()
    End Sub

End Module

I put a file at c:\\temp\\test.abc to test. 我把一个文件放在c:\\temp\\test.abc进行测试。 With this in it: 有了这个:

5tmodvVa640xaDv0fZ650R85uWo0R 5tmodvVa640xaDv0fZ650R85uWo0R
CqwhYMD9e8h CqwhYMD9e8h
FIEeAHhER6Qm2sWY38tKYO FIEeAHhER6Qm2sWY38tKYO
i7diJRVGiZJUZHx26URbCwsewhby3NhPLMSMOv i7diJRVGiZJUZHx26URbCwsewhby3NhPLMSMOv
w51Ft4I8aK2bjdu0OmzD3V5tDjlXnCXGfTk1NqAE w51Ft4I8aK2bjdu0OmzD3V5tDjlXnCXGfTk1NqAE
PlayerCharacterName.....StrProperty.............CHARACTERNAMEHERE PlayerCharacterName ..... ............. StrProperty CHARACTERNAMEHERE
J4H73RcfdMVHkLIaXv J4H73RcfdMVHkLIaXv
Yo5TCC6MmnkA51BZJcrCkzj62xucQ Yo5TCC6MmnkA51BZJcrCkzj62xucQ
8TR1QfSL1IRdmF2ScjjlokTHYHNa2suBk 8TR1QfSL1IRdmF2ScjjlokTHYHNa2suBk
1FBphwSK8aQWdfY1H9tKHSr 1FBphwSK8aQWdfY1H9tKHSr
kLbQvNhUhILdcBv1EXXJgwZtQh37JZu2oXoHuCHRf2bpKsKmlZyf055Q5 kLbQvNhUhILdcBv1EXXJgwZtQh37JZu2oXoHuCHRf2bpKsKmlZyf055Q5
ly0WxwtFP47BE0BAVD1sfWBogFR0Qb9r3DKBWiinRk9xLitqT ly0WxwtFP47BE0BAVD1sfWBogFR0Qb9r3DKBWiinRk9xLitqT
g5FgAyCQ5P7v3Z9hz04hQR1KU1SuoscYH7s5SYbHV1mJEnJKIb0 g5FgAyCQ5P7v3Z9hz04hQR1KU1SuoscYH7s5SYbHV1mJEnJKIb0

And this was the output of my program: 这是我的程序的输出:

Found name "CHARACTERNAMEHERE" 找到的名字“CHARACTERNAMEHERE”

This sounds like a job for a regular expression: 这听起来像是正则表达式的工作:

Public Function GetCharacterName(ByVal filePath As String) As String
    Dim exp As New RegEx("PlayerCharacterName.{5}StrProperty.{13}(.{1,24})")
    For Each line As String In File.ReadLines(filePath)
        Dim result = exp.Match(line)
        If result.Success Then
            Return result.Groups(1).Value
        End If
    Next line
    Return Nothing
End Function

My only concern with this is whether I built the expression correctly (I didn't have Visual Studio or real sample data handy) and whether some of the unprintable characters might produce an unexpected newline or multi-byte character. 我唯一关心的是我是否正确构建了表达式(我没有使用Visual Studio或实际样本数据)以及某些不可打印的字符是否会产生意外的换行符或多字节字符。

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

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