Set EOF

New to FreeBASIC? Post your questions here.
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Set EOF

Post by Juergen Kuehlwein »

Reading the docs i miss something like "seteof(#filenumber)" in PowerBASIC. How can i ensure that an already existing file ends after some data i just wrote to it?

In other words: I already have a file with let´s say 100 bytes of data. Now i change it´s content by writing 50 bytes of new data starting right at the beginning of the file opened in binary mode. This would leave 50 bytes of old data in my file. How can i cut off after 50 bytes, so that subsequent reads would only retrieve the new 50 bytes ?


Thanks


JK
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Set EOF

Post by MrSwiss »

The way I'd approach the situation, as stated by you ...

1) kill (delete) current file
2) open (as new) file, with the same 'name.ext'
3) write to it
4) close it
finished ... (closing it, takes care of EOF)

Reasoning: just setting EOF, in the middle of a file, isn't truely removing the 'old' data!
Aka: the 'old' file-size (on storage medium) would remain (~100 byte)!

"seteof(#filenumber)" may be doing that (the name then, being somewhat misleading)
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Set EOF

Post by jj2007 »

It shouldn't be necessary at all. Normally the OS truncates the file anyway. Try something like this (pseudo code):

Code: Select all

  Open "O", #1, "test111.txt"
  Print #1, String$(50, "xy")	; 50*2=100 bytes
  Close
  Open "O", #1, "test111.txt"
  Print #1, String$(15, "abcd")	; 15*4=60
  Close
  MsgBox 0, FileRead$("test111.txt"), "Hi", MB_OK
P.S.: Real FB code (there is no String$?):

Code: Select all

  Open "O", #1, "test111.txt"
  Print #1, "xyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxy"
  Close
  Open "O", #1, "test111.txt"
  Print #1, "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
  Close
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Set EOF

Post by MrSwiss »

jj2007 wrote:Real FB code (there is no String$?)
in -lang FB, the 'oldfashioned' type-identifiers (&, $, #, etc.) are prohibited!

Do us all a favour and stop, sidetracking the thread.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Set EOF

Post by fxm »

Documentation [url=https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgOpen][b]OPEN[/b][/url] page wrote: .....
Dialect Differences
  • The -lang qb dialect supports the old GW-BASIC-style syntax OPEN mode_string, #filenumber, filename [length] with mode_string being "I" for input, "O" for output, "A" for append, "R" for random, "B" for binary.
.....
Currently, this above syntax is also supported by -lang fb, but this is not a requirement for the parser (this may not be supported later).
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Set EOF

Post by jj2007 »

MrSwiss wrote:Do us all a favour and stop, sidetracking the thread.
What does your shrink say about these symptoms?
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Re: Set EOF

Post by Juergen Kuehlwein »

Of course killing and creating new is always an option, but, yes, "Print #..." does, what i was looking for. I tried "Write #..." and it added double quotes to my string data, this is, what i didn´t want either.

Thanks - problem solved


JK
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Set EOF

Post by deltarho[1859] »

Well, it may work with Print but not with Put. To satisfy the second paragraph of the opening post the safest bet is to Kill an existing file.

I use this a lot.

Code: Select all

#Include "file.bi"
If FileExists(<filename>) Then Kill <filename>
jj2007 wrote:What does your shrink say about these symptoms?
Good question. I bet the shrink has his work cut out, and no mistake. However, I should imagine that it would be very much cheaper to take pills.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Set EOF

Post by jj2007 »

deltarho[1859] wrote:the safest bet is to Kill an existing file.
Actually, this is what Open "O", #1, "test111.txt" does; deep in the guts of the CRT, there is this line:

Code: Select all

call near [<&API-MS-Win-Core-File-L1-1-0.CreateFileA>]
I can't speak for Linux, of course, but CreateFile kills the existing file and creates a new one. Interesting btw that FB (or rather, GAS) uses the Ansi variant.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Set EOF

Post by deltarho[1859] »

CreateFile isn't just about creation and we also have ReadFile and WriteFile. There is a fair amount of reading in that lot.

At the end of the day if a file exists and we have no interest in it's contents and we want to use the same filename then, as I said, the safest bet is to Kill the existing file and is doesn't matter what BASIC dialect is used and how they implement the underlying system functions, what language or what operating system - we simply cannot put a foot wrong. In other words we cannot be bitten in the bum by introducing a filename if that filename does not currently exist.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Set EOF

Post by jj2007 »

deltarho[1859] wrote:CreateFile isn't just about creation
Right, but in this specific case the CRT uses the CREATE_ALWAYS flag, so it does kill an existing file and creates a new one. Again, no idea how Linux handles this, and it would be good to clarify this in the docs. Your solution works, of course, but if the observed behaviour was properly documented,*) I would consider check for existence & kill a duplication of the procedure that the OS performs anyway.

*) It is indeed documented in the Open page:
The Output mode is like the Append mode, except that if the file exists then its contents are deleted and its length reset to zero before writing
Back on topic:
Juergen Kuehlwein wrote:I already have a file with let´s say 100 bytes of data. Now i change it´s content by writing 50 bytes of new data starting right at the beginning of the file opened in binary mode. This would leave 50 bytes of old data in my file. How can i cut off after 50 bytes, so that subsequent reads would only retrieve the new 50 bytes ?
There are situations where you don't start at the beginning of the file, but rather somewhere in the middle. If you write 50 bytes from position 20, and want to see 70 bytes and not more after closing the file, the solution (in the absence of SetEof) would be to read the first 20 bytes into a buffer, then open the file for output, print the 20 bytes, print the 50 bytes, close the file. Clumsy but it works.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Set EOF

Post by deltarho[1859] »

There is a danger in talking specifics. The Output mode indeed truncates to zero bytes before writing.

In the docs, Open page, there is an example: ' Create a string and fill it.

This creates a file, file.ext, 26 bytes in size.

If we run that again with buffer = "jj2007" we find that file.ext is still 26 bytes but now with the first 6 bytes as "jj2007". It would not surprise me to learn that one or two here did not expect that.

I almost invariably use Binary mode so I need to Kill existing files.

If anyone switches from OutPut to Binary for some reason and are not au fait with the docs then they could be in trouble.

Well, it could be said that it is their fault for not reading the manual but I do not take that view since everyone of us, at sometime or other, has not read every word of a keyword's description.

So, for the third time I will use the term 'safe bet'. I am pedantic by nature but there are times when I am the opposite. The thing about 'safe bets' is that we cannot lose any money.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Set EOF

Post by jj2007 »

deltarho[1859] wrote:I almost invariably use Binary mode
That explains it: binary and random will not truncate, of course. In contrast, I use this "update" mode only in those rare cases when I have to change some bytes inside an existing file, e.g. for patching.

The doc is remarkably vague on this, so perhaps it's good that we now have this thread for clarification.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Set EOF

Post by fxm »

Opening a file in Binary (or Random) mode and also in Write (only) access mode allows you to first delete any previous record in the file (the file becomes empty before any writing operation).
adele
Posts: 47
Joined: Jun 13, 2015 19:33

Re: Set EOF; truncate

Post by adele »

Hi, truncate for Win , Linux: no idea

Code: Select all

'trunc
' notDOCed, but works: truncate, 
' found somewhere in the C-RTL
' WIN only :(
#Include "File.bi" ' for "Filelen()"
declare function truncate Cdecl alias "truncate" ( _
 byval __file as zstring ptr, _
 byval __length as LongInt ) as Long 

Open "my.dat" As #1 Len = 1
' Field #1,1 As aStr
Var aStr="?"
Put #1,1200,aStr
Close
Print Filelen("My.dat")
truncate("My.dat",777)
Print Filelen("My.dat")
Sleep
Maybe that´s what you are looking for?
Of course, you should know the desired new length, maybe get it with
NewLen=seek(FileNo)
Be aware: with an opened file, it might cause problems, so better close() b4 truncate()
Adi
Post Reply