writing a line into a file..?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
steven777
Prole
Posts: 35
Joined: Tue Jul 12, 2016 4:48 am

writing a line into a file..?

Post by steven777 » Tue Jul 19, 2016 6:53 am

so im trying to write a line into a file. i know what like i want to delete and replace but for some reason i just cant get the line to be removed and replaced...

the reason for this is user information updating on the server so the line contains serveral bits or data but im just going to re write the whole line.


right now im deleting the whole fine and re creating it... but i think this is going to be real bad when there are many users trying to update at once...


i just want the line to be removed and replaced ?? anyone have a way of doing this, i cant seem to find any reference maternal besides string library lol.


so what happens is when a payer updates it just replaces his info into the line(which is already indexed) i just have no way of re writing it,,,

User avatar
Pangit
Party member
Posts: 148
Joined: Thu Jun 16, 2016 9:20 am

Re: writing a line into a file..?

Post by Pangit » Tue Jul 19, 2016 7:06 am

Open your file (read)- then you read your file into a table, you replace the portion of the table with the data you want. Then you write that table back to the file (or a new file - whatever you want).

There are other things you can do. Generally I go with the brittle approach of just assuming that the data is going to be at line n, and amend my table at that n. But to handle a situation where a file could have data at different portions really you should be searching the table for the data you want to amend. But that will take time. So if you know for sure that the position of the data will not change. Then you go with the first. If a file is a bit more unclear where it will store the information you want then your need to search for it.

The code is slightly different depending on if you are working with a binary file or a text file. But the main thing to remember is to close the file stream. And pay attention to the type that you assign to the stream (read, write, read+write) Common got-cha with files is trying to write to a stream that is read and vice versa.

If the file is huge there are some weird errors you will get using the above method. But for something like a configuration file its not going to be a problem.

On something that has multiple writes, and you might have corruptions from re-writes at the same time you need to think about using a database to manage the data then your program talks to the database and makes requests to that instead of directly messing with a flat file. The advantage is the database can handle multiple access requests and avoid the problem of corruption like you would have with the flat file.

Then you are looking at your server configuration. How much ram do you have? how big is the file. Fastest way is to keep the database in memory - Riak is a good example of this. Very simple to use. It is nice for things like high-score lists, ect.. Anything where you need high-availability and speed.

Like on a server for example - you have clients that send there player position data and other commands that affect the game world. In return the client wants an update of the game world from the server. In a database were assume that your game has only one room to keep it simple.

The server would dispatch a update to each client that was accessing the server with the data that the client would use to run the game.
The advantage of using the database is you would have each clients position and what it was doing as keys in the database. Depending on the client connection each should receive a up-to date picture of what's happening across all the clients in a shared space.

I don't see how you could do this with flat files, not without errors anyway or reimplementing a database.

steven777
Prole
Posts: 35
Joined: Tue Jul 12, 2016 4:48 am

Re: writing a line into a file..?

Post by steven777 » Tue Jul 19, 2016 7:46 am

so how do i insert it at the line? i cant find examples of it. i understand how it works.just not the function to delet a line and replace it lol.


in my server all of the players that have an account possible are loaded into a table at the start of the server so it can be handled fast. no need to keep opening and closing files. the tables are indexed at the same as the position was in the file, <--- thats how i know where my update line is, but i still need an example

i need an example of a basic script that could show me the insertion of a line. and also how to delet the line.

User avatar
Pangit
Party member
Posts: 148
Joined: Thu Jun 16, 2016 9:20 am

Re: writing a line into a file..?

Post by Pangit » Tue Jul 19, 2016 7:51 am

let me have a dig around... I think i have an xml writer somewhere.

but to give you a hint - you look at your file. Note the line where the data that you want to mess with lives. for example in my xml writer it was at a location of line 1085 in the file. I wrote that down.

Then in my lua script I loaded the file into the table, then I just did mytable[1065] = "the new data"

This then has updated your table, it was then just a matter of writing the table to the file.

Let me look for the script...

steven777
Prole
Posts: 35
Joined: Tue Jul 12, 2016 4:48 am

Re: writing a line into a file..?

Post by steven777 » Tue Jul 19, 2016 7:54 am

i can edit the table values easy. i,m just not sure on the syntax for updating said line. one sec ill pull up somthing i think may work idk yet

edit:

i really wish

love.filesystem.write( name, data, size ) had a line number for insertion

steven777
Prole
Posts: 35
Joined: Tue Jul 12, 2016 4:48 am

Re: writing a line into a file..?

Post by steven777 » Tue Jul 19, 2016 8:08 am

f = io.input ("test.txt")
repeat
s = f:read ("*l") -- read one line
if s then -- if not end of file (EOF)
print (s) -- print that line
end
until not s -- until end of file

f:close () -- close that file now


here is the stadard io libray for lua but its edited to show wht i want bellow

f = io.input ("test.txt")

s = f:read ("*l") -- read one line
repeat
index = index+1 -- an index number for each line
if index = slot then -- the line we want to change
f:write() <----- write the new data to the line
end
until not s -- until end of file

f:close () -- close that file now

User avatar
Pangit
Party member
Posts: 148
Joined: Thu Jun 16, 2016 9:20 am

Re: writing a line into a file..?

Post by Pangit » Tue Jul 19, 2016 9:08 am

Code: Select all

-- readline = the line number you want within the file test.txt
readline = 7

-- lines is the n-1 (where were are counting from 0 so its actually 2..)  We are telling the for loop how many times to cycle.
lines = readline - 2

-- the magic, iter is reading each line of the file in order on each cycle of the for loop. 

iter = io.lines 'test.txt'

-- checking that there are enough lines in the file.

for i=0, lines do
    if not iter() then
        error 'Not enough lines in file'
    end
end
 
line = iter()

-- print the line to the screen

print(line)
Problem with this is its great for reading.. writing not so hot.. your still looking at updating the table so far as I can tell then writing the file. But then its not clear from any of the documentation how to do this.

You can remove lines from a file...

Code: Select all

function remove( filename, starting_line, num_lines )
    local fp = io.open( filename, "r" )
    if fp == nil then return nil end
 
    content = {}
    i = 1;
    for line in fp:lines() do
        if i < starting_line or i >= starting_line + num_lines then
	    content[#content+1] = line
	end
	i = i + 1
    end
 
    if i > starting_line and i < starting_line + num_lines then
	print( "Warning: Tried to remove lines after EOF." )
    end
 
    fp:close()
    fp = io.open( filename, "w+" )
 
    for i = 1, #content do
	fp:write( string.format( "%s\n", content[i] ) )
    end
 
    fp:close()
end

-- this removes the first line in the file.
remove("test.txt",1,1)
That was from Rosetta stone, you could use this as a template to put your string into the table (content) before the write back..
https://www.rosettacode.org/wiki/Remove ... a_file#Lua

This was the technique I used in the XML writer program I couldn't find.

Here is your insert function...

Code: Select all

function justTheTip( filename, starting_line, num_lines, chord )
    local fp = io.open( filename, "r" )
    if fp == nil then return nil end
 
    content = {}
    i = 1;
    for line in fp:lines() do
        if i < starting_line or i >= starting_line + num_lines then
	   content[#content+1] = line
	end
	i = i + 1
    end
 
    if i > starting_line and i < starting_line + num_lines then
	print( "Warning: Tried to remove lines after EOF." )
    end
 
    fp:close()
    fp = io.open( filename, "w+" )
    
    content[starting_line]=chord
    
    for i = 1, #content do
	fp:write( string.format( "%s\n", content[i] ) )
    end
 
    fp:close()
end

-- Ok so the first parameter is a file, second is the line number, 
-- third is the number of lines after you want to erase, the final string is what you want to update the file with.

justTheTip("test.txt", 2, 0, "Denki Groove")

User avatar
pgimeno
Party member
Posts: 2335
Joined: Sun Oct 18, 2015 2:58 pm

Re: writing a line into a file..?

Post by pgimeno » Tue Jul 19, 2016 2:25 pm

Files are continuous binary streams of data. They are not organized in lines, but in sectors. If you need to insert or delete data in a file, *everything* that comes after that change must be rewritten to accommodate for the size variation. For example, if a file is 1GB long, and you want to delete a byte in position 200, then the byte at position 201 must be written to 200; the byte at position 202 must be written to 201, ... the byte at position 1GB-1 must be written to position 1GB-2, and finally the file must be truncated to 1GB-1. No way to do that without rewriting every sector starting from that position. And expanding a file is even harder.

No software I know allows you to replace a line in a file without rewriting it entirely. That includes editors: they rewrite the whole file every time you save.

If you need files organized in records of a certain length, that's what databases are about. Unfortunately, LÖVE doesn't include a database management system.

steven777
Prole
Posts: 35
Joined: Tue Jul 12, 2016 4:48 am

Re: writing a line into a file..?

Post by steven777 » Tue Jul 19, 2016 11:29 pm

ok so here is my new question. right now its updating one line at a time... now i need somthing new to update the whole file from the user data tables. see the saving code below(modified)

Code: Select all

	 function file_update( filename, index, iterations) 

	    local fp = io.open( filename, "r" )
	    if fp == nil then return nil end
	 
	    	local content = {}
	    	
	   		i = 1;
	    for line in fp:lines() do -- iterate threw lines 
	        if i < index or i >= index + iterations then --if i =key < index or index is greater than index +iterations
	      		content[#content+1] = line -- content = line at line index
	   		end
	  			i = i + 1
	    end 
	 
	    if i > index and i < index + iterations then -- warning/ error
	   		print( "Warning: Tried to remove lines after EOF." )
	    end
	  
	    fp:close() 
	    fp = io.open(filename, "w+" )

	   	local chord = string.format("%s%s%s%s%s%s%s%s%s",player_data_table.name[index],"|",player_data_table.pass[index],"|",player_data_table.auc[index],"|",player_data_table.prokey[index],"|",player_data_table.ip[index])

	    print(chord)
	    content[index]= chord
	  
	    for i = 1, #content do
	  	 fp:write( string.format( "%s\n", content[i] ) )
	    end
	    fp:close()
	    
	end




i really dont want to have to use this to update the thing every now and then

-- or somthing like this to get it to save. i do like the ability to save an idividual line and will be used for important updates in other systems. possably

Code: Select all

 

function file_update_all(dt)
	system_refresh_rate = system_refresh_rate + dt
	if system_refresh_rate > system_refresh_ratemax then
		system_refresh_rate = 0
		for i = 1,#player_data_table.name do
			file_update( "main_server_files/userdata.lst", i, 0)
		end
	end
end



so what im trying to do is load the full player table which is this ( player_data_table = { tabel,table,table } )


its timmed so say every 5 min it updates everyone at once. cutting down on response times.

steven777
Prole
Posts: 35
Joined: Tue Jul 12, 2016 4:48 am

Re: writing a line into a file..?

Post by steven777 » Wed Jul 20, 2016 12:56 am

currently the code above runs fine. it does have to call the function to save for each object in the table so it iterates allot over the strings. anyone just have a way to do the whole file?

Post Reply

Who is online

Users browsing this forum: myQwil and 29 guests