SeekFile help

Blitz3D Forums/Blitz3D Programming/SeekFile help

Yue(Posted 2012) [#1]
Hello ltengo a concern regarding this command. In support tells me about a formula to calculate the offset into the file I want to see, eg if I have three numbers with this command I set it on 4 and I would read the second integer file.

Now the roll is that I can not understand what the Formual calculated and not how to implement it.

Another issue is that only whole numbers.?


GfK(Posted 2012) [#2]
I have no idea what you're talking about, first of all.

On the assumption that you have three integers (four bytes each), then the first integer occupies bytes 0-3, the second occupies bytes 4-7, and the third, 8-11. So simply multiplying 'n' by 4 would give you the file offset to read the integer from.

Another issue is that only whole numbers.?
only whole numbers... what? I don't understand.


RifRaf(Posted 2012) [#3]
you have to seek to byte locations

byte = 1 position
integer = 4 bytes
float = 4 bytes
string = 4 byte integer header showing length + byte per char


You can google longs and all that, for blitz3D though i think the above is all you need.

Last edited 2012


Midimaster(Posted 2012) [#4]
Is the file, that you have a "self made" file, which you created with WriteFile() or OpenFile()?

Or is it a file, that comes from a other software?

In the Menu "Help" of Blitz-3D you will find the command SeekFile() and a nice example, which you could study. It says all about writing seeking and reading files.

If you stored INTEGERs with WriteFile() and WriteInt() commands...
FileHandle=WriteFile("test.dat")
     WriteInt FileHandle,123
     WriteInt FileHandle,999
     WriteInt FileHandle,-6
CloseFile FileHandle


..., you can later open the file an read it with ReadFile() and ReadInt(). The file cursor will automatically jump to the next correct position:
FileHandle=ReadFile("test.dat")
     A=ReadInt(FileHandle)
     B=ReadInt(FileHandle)
     C=ReadInt(FileHandle)
CloseFile FileHandle
Print A + "   " + B + "   " + C



If you do not need A you can jump over with SeekFile():
FileHandle=ReadFile("test.dat")
     SeekFile FileHandle,4
     B=ReadInt(FileHandle)
     C=ReadInt(FileHandle)
CloseFile FileHandle
Print A + "   " + B + "   " + C

Because a INTEGER is 4 Bytes long you have to jump 4 Bytes in the File

The value of A is at position 0 in the file
The value of B is at position 4 in the file
The value of C is at position 8 in the file



You can jump to any position in the file, also backwards:
FileHandle=ReadFile("test.dat")
     SeekFile FileHandle,8
     C=ReadInt(FileHandle)
     SeekFile FileHandle,0
     A=ReadInt(FileHandle)
CloseFile FileHandle
Print A + "   " + B + "   " + C


But be careful, if you jump "between" the INTEGERs you will not get an ERROR, but you will get wrong values:
FileHandle=ReadFile("test.dat")
     SeekFile FileHandle,3
     C=ReadInt(FileHandle)
CloseFile FileHandle
Print "wrong C= " + C



Yue(Posted 2012) [#5]


Ok, I understand the matter concerning the integers, however this can be used in text strings in files almacenads?.

What I can not understand exactly is the formula that says and not referred.

For example a file of integers are 4 bytes long Which is Calculated by:

The 7th integer is at offset 7 * 4-4 i.e. 24


Floyd(Posted 2012) [#6]
The offset is simply the number of bytes which precede the location you want to access. If you are looking for the 7th integer then you must move past the previous 6 integers and the offset is 6*4 = 24.

If you want to read text strings then you must know how the strings are stored. The Blitz WriteString command stores an integer ( the number of characters in the string ) followed by the actual text.

But most text is not stored like this. Instead, a line of text is followed by an end of line marker. This would usually be the two bytes 13 and 10, which mean carriage return and line feed. The Blitz WriteLine command does this.

There are other possibilities. You need to know how the file was created.


Midimaster(Posted 2012) [#7]
Do you means this?

"The position of the 7th INTEGER is 24, but the file size of course is 28 Byte."

To your questions about text files:
It would help, if you tell us, what you want to do with the text file. Perhaps there is a better way the ReadInt() and FileSeek()

And it would help if you tell us, where the txt file was created. In which software? Which ending? " Is it *.txt" or "*.doc" or ...?

"Almacenads" es un po espanol? You mean "saved files"?


Yue(Posted 2012) [#8]
@Midimaster

sorry my english is bad, i am use google translator, sorry... Almacenados = stored

To find the size of the item, the file is not it, then use FileSise?

The 7th integer is at offset= FileSize * 4-4 i.e. 24

Correct??

The text strings is considered making a database with player names and score esteblecer the maximum and minimum. (Scoring system) and manage the player's name.

Last edited 2012


RifRaf(Posted 2012) [#9]
7 integer offset is ( 7 * 4 )
7 integers @ 4 bytes each


Midimaster(Posted 2012) [#10]
so... the text file is made by you? It is made by BlitzBasic?

So you could write it with WriteLine() and read it with ReadLine(). That is easy:

A line contains the name of the player and his score and other values of the player. The "|" is used as a separator sign:
Player A | 1400 | 4 |

Yue | 2345 | 6 |

Midimaster | 45 | 1 |




Add a new player to the file:


[bbcode]
Function AppendAPlayer( Name$, Score%, Level% )
;first create a string with the players data:
locString$ = Name + "|" + Score + "|" + Level + "|" ; + ...whatever

; then open the file
If FileType("test.dat")=0
locFileSize% = 0
FileHandle% = WriteFile("test.dat")
Else
locFileSize% = FileSize("test.dat")
FileHandle% = OpenFile("test.dat")
Endif

; now skip to the end and write the data
SeekFile FileHandle, locFileSize
WriteLine FileHandle, locString

CloseFile FileHandle
End Function
[/bbcode]


This to find again a player:

[bbcode]
Function FindAPlayer( SearchName$ )
; open the file
FileHandle% = OpenFile("test.dat")

; search until the end of the file is reached
While Eof(FileHandle)=0

; read one line
locString =ReadLine(FileHandle)

; separate it in single values:
For i%=1 to 3 ; or 4 or 5...depending on the nuber of values
; find the position of the separator:
Separator%=Instr (locString, "|" )

;cut the left part as the value
locValue$= Left(locString, Separator-1 )
Select i
Case 1
Name=Value
Case 2
Score=Int(Value)
Case 3
Level=Int(Value)
End Select

; if you found the current player close the file:
If Name = SearchName Then
CloseFile FileHandle
Return
Endif

; cut the rest for searching again
locString= Mid(locString, Separator+1, -1 )
Next
Wend
CloseFile FileHandle
End Function
[/bbcode]


Now find all players for a highscore list:

[bbcode]
Function GetAllPlayers()
; open the file
FileHandle% = OpenFile("test.dat")

; search until the end of the file is reached
While Eof(FileHandle)=0

; read one line
locString =ReadLine(FileHandle)

; separate it in single values:
For i%=1 to 3 ; or 4 or 5...depending on the number of values
; find the position of the separator:
Separator%=Instr (locString, "|" )

;cut the left part as the value
locValue$= Left(locString, Separator-1 )
Select i
Case 1
Player.TPlayer = New TPlayer
Player\Name=Value
Case 2
Player\Score=Int(Value)
Case 3
Player\Level=Int(Value)
End Select

; cut the rest for searching again
locString= Mid(locString, Separator+1, -1 )
Next
Wend
CloseFile FileHandle

; list all Players:
For loc.TPlayer = Each TPlayer
Print loc\Name + " " + loc\Score + " " + loc\Level
Next
End Function
[/bbcode]


Find a existing Player and change his values:

In this case you open the file as for a highscorelist (see above). Then search for the player, change his values and save all players:

[bbcode]
Function ChangeAPlayer( SearchName$ ,Score%, Level%)
GetAllPlayers()

; search the Players:
For loc.TPlayer = Each TPlayer
If loc\Name = SearchName
Found =TRUE
; change his values:
loc\Score = Score
loc\Level = Level
Next

If Found=FALSE
;it is a new player:
AppendAPlayer(Name,Score,Level)
Return
Endif

; player was found, so save all datas:

FileHandle% = WriteFile("test.dat")

For loc.TPlayer = Each TPlayer
;create a string with the players data:
locString$ = Player\Name + "|" + Player\Score + "|" + Player\Level + "|" ; + ...whatever
WriteLine FileHandle, locString
Next

CloseFile FileHandle
End Function
[/bbcode]


Yue(Posted 2012) [#11]
:) Ho! Thanks you Midimaster