问题
Good afternoon StackOverflow,
I've just signed up here - I've been using this site for ages, and it seems to always be the site to supply the answer so I decided to be part of things.
Without further ado, here is my question -
I am writing an API for LAN parties that me and a group have monthly to help sort things out on the scorekeeping side. My friend is writing the backend for it, and I'm writing the VB6 frontend. It's been a while since I wrote VB6, and I never wrote it as intensively as the grade of frontend I'm aiming for here.
The premise of the program is this - The backend will write events from the game we're playing to a text file in realtime - Which the frontend reads from in realtime. The part I'd like to enquire about at the moment is this -
I know you can read text files line-by-line in VB6. I want the program to 'listen' (so to speak) for certain buzzwords and use their defined 'Values' to affect variables. Here is a mock example of the kind of file it'll be reading -
******************
LANrealm Match Log
******************
Game: Call of Duty 4
Game Type: Team Deathmatch
Date: 01-Jan-2013
Time: 19:00:00
Players: Tramp
Roper
d00b
Pleb
Score Limit: 150
Event: Game Start
Event: Roper killed Pleb (M4A1) shots=5 Feet=2 Body=2 Head=1
Event: Tramp committed suicide (Fall damage)
Event: Tramp killed d00b (Grenade)
Event: Pleb said "I'm saying something"
Event: Pleb teamkilled d00b (G3) shots=3 Feet=0 Body=2 Head=1
Event: Game Finished
Winner: Roper
Roper: Kills=1,Deaths=0,Suicides=0,Teamkills=0
Tramp: Kills=1,Deaths=0,Suicides=1,Teamkills=0
Pleb: Kills=0,Deaths=0,Suicides=0,Teamkills=1
d00b: Kills=0,Deaths=0,Suicides=0,Teamkills=0
Well, I think just by looking at this you can tell what I want the program to pick out of that. It would be a lot easier if I just made it fully comma delimited, but I want to maintain readability of the raw text file. But yeah, just in case you didn't get it, I'd want the program to recognise that 'Roper' had 1 'Kill' and so on and so forth. An example code snippet would be great!
Thanks in advance, guys.
回答1:
Here's a function you could use to load the contents of a file:
Public Function LoadFile(dFile As String) As String
Dim ff As Integer
On Error Resume Next
ff = FreeFile
Open dFile For Binary As #ff
LoadFile = Space(LOF(ff))
Get #ff, , LoadFile
Close #ff
End Function
Next, you want to split the output of that file. First, you will need to know what type of EOL termination character will be produced by the back-end. Assuming each line ends with a carriage return (13) and a line feed (10), you could use this code to store each line into a string array:
Dim lines() As String
lines = Split(LoadFile("LANrealm.log"), vbCrLf)
Finally, it's a matter of cycling through each line (using a For...Next loop) and look for whatever information you want to extract:
For i = 0 To Ubound(lines)
' Add here necessary logic to extract the information.
' Each line can be accessed by indexing the array as: lines(i)
Next
Hope this helps you get started...
To test the code:
- Start VB6 and create a new project. VB6 will create an empty project with one form
- Double click the form to view it
- Right click the Toolbox and select "Components"
- Locate the "Microsoft Common Dialog Control" and select it
- Click OK
- Now, drag the "CommonDialog" component from the Toolbox onto the form
- Double click the form to view its source code
- Paste the following code
NOTE: Make sure you overwrite any pre-existing code
Option Explicit
Private Sub Form_Load()
cDlg.DefaultExt = "txt"
cDlg.Filter = "Text Files|*.txt;*.log"
cDlg.ShowOpen
If cDlg.fileName <> "" Then AnalyzeFile .fileName
End Sub
Private Sub AnalyzeFile(fileName As String)
Dim fileContents As String
Dim lines() As String
Dim i As Integer
fileContents = LoadFile(fileName)
lines = Split(fileContents, vbCrLf)
For i = 0 To UBound(lines)
If InStr(1, lines(i), "event:", vbTextCompare) Then
MsgBox "Line #" & i & " contains the string 'event'" + vbCrLf + vbCrLf + lines(i)
End If
Next
End Sub
Private Function LoadFile(dFile As String) As String
Dim ff As Integer
On Error Resume Next
ff = FreeFile
Open dFile For Binary As #ff
LoadFile = Space(LOF(ff))
Get #ff, , LoadFile
Close #ff
End Function
Run the program and, when asked to supply a file, select one of the logs that will be generated by the back-end.
In this example, the program will tell you which lines contain "event information", such as "Event: Roper killed Pleb (M4A1) shots=5 Feet=2 Body=2 Head=1".
回答2:
One problem I would see doing this in real-time, reading and writing is if two or more computers or apps try to open the same file. This could be a bit of a mess.
回答3:
Ok, so if you REALLY want to read your file line by line, I would change your logfile a little different.
******************
LANrealm Match Log
******************
Game: Call of Duty 4
Game Type: Team Deathmatch
Date: 01-Jan-2013
Time:1 9:00:00
Players: Tramp, Roper, d00b, Pleb
Score Limit: 150
Event: Game Start
Event: Roper killed Pleb (M4A1) shots=5 Feet=2 Body=2 Head=1
Event: Tramp committed suicide (Fall damage)
Event: Tramp killed d00b (Grenade)
Event: Pleb said "I'm saying something"
Event: Pleb teamkilled d00b (G3) shots=3 Feet=0 Body=2 Head=1
Event: Game Finished
Winner: Roper
Stat: Roper Kills=1,Deaths=0,Suicides=0,Teamkills=0
Stat: Tramp Kills=1,Deaths=0,Suicides=1,Teamkills=0
Stat: Pleb Kills=0,Deaths=0,Suicides=0,Teamkills=1
Stat: d00b Kills=0,Deaths=0,Suicides=0,Teamkills=0
You can use this to read the file line by line.
Dim FileNo As Integer
Dim TempData As String
Dim TempStr As String
FileNo = FreeFile
Open "c:\game.log" For Input As FileNo
Do
Line Input #FileNo, TempStr
TempData = TempData & TempStr or do what ever you want it to do with that line.
DoEvents
Loop Until EOF(FileNo)
Close #FileNo
MsgBox TempData
However, I would suggest to read the whole file into a string, and then parse out info you want. If you did, you can then pick out info you might want, like name of game etc.....
Try this. Create a new module, and paste this in it.
Public Function ParseData(DataSTR As String, StartSTR As String, EndSTR As String) As String
Dim Split1
Dim Split2
Split1 = Split(DataSTR, StartSTR, , 1)
Split2 = Split(Split1(1), EndSTR, , 1)
SplitParse = Split2(0)
End Function
Then add this to a command button.
Private Sub Command2_Click()
Dim FileNo As Integer
Dim TempData As String
FileNo = FreeFile
Open "c:\game.log" For Input As FileNo
TempData = Input(LOF(FileNo), FileNo)
Close
MsgBox TempData
MsgBox Trim(ParseData(TempData, "Game:", Chr(10)))
End Sub
Now this is just a sample of what you can do.
来源:https://stackoverflow.com/questions/14340904/vb6-reading-text-files-line-by-line-looking-for-specific-words