Forum

> > CS2D > Scripts > File append often does not work
Forums overviewCS2D overview Scripts overviewLog in to reply

English File append often does not work

8 replies
To the start Previous 1 Next To the start

old File append often does not work

Quattro
GAME BANNED Off Offline

Quote
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function add_newbies()
local file = 0
local report_l = 0
local steamid = 0
local nick = 0
	for i = 1, 32 do
		if player(i,'exists') then
			steamid = steam(i)
			nick = name(i)
			if steamid ~= 0 then
				if member_data(steamid,1) == 0 then
					file = io.open("sys/ranks/areports.txt", "ab")
					if not file then msg('©255100100Internal error: Could not read "sys/ranks/areports.txt"') return end
					report_l = 'A-'..nick..'-'..steamid
					file:write(report_l,'\r\n')
					file:close()
					msg('©200200200OMG a Newbie! '..player(i,'name')..' earns newbie bonus: ©100255100+1500©200200200 rank points!')
				end
			end
		end
	steamid = 0
	end
run_calculator()
end

What happens with this code: I always get the new player message but for some reason I have to run this function twice or several times before it actually appends the report_l. I also never see Error report that I added, so it opens file but doesn't write to it?

Why doesn't it work correctly?

old Re: File append often does not work

Rainoth
Moderator Off Offline

Quote
Correct me if I'm wrong but there's always going to be a file because append mode will create one if it doesn't exist, that's why.
Your written data is not saved because you don't save it.
You do it with file:flush() (assuming 'file' is where you keep you keep the file descriptor)

Again, correct me if I'm wrong since I don't normally use these functions.

old Re: File append often does not work

Yates
Reviewer Off Offline

Quote
Mode should be
a
, I don't think
ab
even exists.

You also return with the error message but never close the file, you also don't need to return an error because you're going to write in it anyway. Remove that whole line.

old Re: File append often does not work

DC
Admin Off Offline

Quote
@user Yates: The "b" is for binary. https://www.lua.org/pil/21.2.html

The data however is not binary but a string. So yes, the b should be removed.

@user Rainoth: In most languages close also flushes. Unfortunately the official Lua documentation says nothing about the exact behavior but I would assume that an additional flush is not required.

In general it's a bad idea to open and close a file so frequently. File operations are very slow compared to other operations. You should open the file before the loop once, do all write operations and close it afterwards.

For best performance you should even do another loop beforehand and only open the file if you actually need to write something.

Also don't concatenate data just to write it (concatenation is expensive too).
Instead of doing this:
1
2
report_l = 'A-'..nick..'-'..steamid
file:write(report_l,'\r\n')
you should do this:
1
file:write('A-', nick, '-', steamid, '\r\n')
(okay, it doesn't really matter with your amount of data but this would be best practice)
edited 1×, last 17.06.18 10:30:37 am

old Re: File append often does not work

Quattro
GAME BANNED Off Offline

Quote
user Rainoth has written
Correct me if I'm wrong but there's always going to be a file because append mode will create one if it doesn't exist, that's why.
Your written data is not saved because you don't save it.
You do it with file:flush() (assuming 'file' is where you keep you keep the file descriptor)

Again, correct me if I'm wrong since I don't normally use these functions.


I haven't tried it yet but I think you are right, I read about it on some forums and there is a chance my script writes data to buffer instead of text file. I am looking forward to see if flushing fixes the problem

@DC I added binary because some people said it fixed some rare errors for them
By the way, is it true about what Yates said that error message is useless and I have to close file? I thought 'if not file' means it failed to open so you don't have to close it?

Ty for tips!

old Re: File append often does not work

Yates
Reviewer Off Offline

Quote
The only way this will fail is when the directory does not exist. So yes, you can remove that whole line as long as you make sure it always exists.

Do it.

old Re: File append often does not work

Rainoth
Moderator Off Offline

Quote
@user Quattro: Like I said, append mode will create a file for you, so some of the cases I can think of would be if you ran out of memory to read data (say you had 1GB text file but only 512MB of RAM ) or if you ran out of disc space to create a new text file (?) or if the directory didn't exist.

// kinda ninja'd

old Re: File append often does not work

DC
Admin Off Offline

Quote
It will also fail if you don't have the required file system permissions to write the file or if the file is locked because another process is currently accessing it.

So it's good to have that error message and to return. Otherwise your code would break in these and the above scenarios.

Good code handles all edge cases properly without exploding
Removing already implemented error handling just because the handled errors don't occur frequently would be quite stupid.

old Re: File append often does not work

Quattro
GAME BANNED Off Offline

Quote
I agree @DC, that was the reason I added it in the first place and it already was useful once (probably last time too)

Btw it was indeed a problem of write buffering: io.flush forces to write buffered text and fixes the problem. That's why it sometimes wrote and sometimes not without flush - it was waiting for buffer to max out and write in bulk.

There is also a solution to set buffer size after each use, but io.flush is much easier to remember.
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview