Jump to content

Lua - File I/O


Koregan

Recommended Posts

I would like to handle with files out of a lua script, but i don't get it working.

 

I read different code at certain websites, but nothing does work at all.

It is not possible for me to create any directory or open any files.

 

Does anybody have some example-code for me?

Link to comment
Share on other sites

RoboMat, could you explain how to use your i/o to copy a file 1to1 ?

 

I read out my "test\example.txt":

1234

and wrote my "test2\example.txt".

But "example2.txt" is:

3214

my code was:

function copyFile(_filename)    local inputDir = "test\\";    local outputDir = "test2\\";    local file = FileIO.readFile(inputDir .. _filename, false);    FileIO.writeFile(outputDir .. _filename, file.content, true, false)endCopyTheFiles = function()    copyFile("example.txt")endEvents.EveryTenMinutes.Add(CopyTheFiles );

Any suggestions how i can get a exact copy of the file? Or why the order changed and the new lines gone away?

 

 

 






 

Link to comment
Share on other sites

The reason why the new file is unsorted is that tables in lua - by nature - are unsorted. More information.

 

I will take a look at my FileIO classes and see if I can fix it for the next update - it might take a while though as I'm waiting until SP and MP are merged and stable ^^

 

 

Open the copied file with another reader and it will have the right format. Windows Notepad can´t interpret the EOL.

 

IIRC you can use "\r\n" to get it to work on all system.

 


Another common problem is the use of '\n' when communicating using an Internet protocol that mandates the use of ASCII CR+LF for ending lines. Writing '\n' to a text mode stream works correctly on Windows systems, but produces only LF on Unix, and something completely different on more exotic systems. Using "\r\n" in binary mode is slightly better.

From http://en.wikipedia.org/wiki/Newline#In_programming_languages.

 

Hope that helps.

Link to comment
Share on other sites

P.S.: If you want to have sorted input and output use the ipairs iterator instead of pairs. The reason why I used pairs is that it allows you to access the key of the table. If you use ipairs to iterate over a table with keys of type string it simply won't work.

 

Example:

	t1 = { foo = 1, bar = 2 };	for k, v in pairs(t1) do		print(k, v)	end	-- > Output:	-- foo   1	-- bar   2	for i, v in ipairs(t1) do		print(i, v)	end	-- > No output as ipairs only works on numerical index.
->
Link to comment
Share on other sites

Use the getFileReader and getFileWriter you'll have Java object and no surprise :D

 

Check the MainOptions.lua, you'll see how I do it for the key binding.

 

That's what we use already :P

But yeah MainOptions.lua is where I learned the stuff from, so it is good to look into it :)

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...

I'm glad I stumbled across this post. Not having Lua I/O is a no-go for me.

 

I assume this also means no access to dofile() and loadfile(), correct?

 

I always save data as Lua tables and use loadfile() to get it back. It's the fastest and easiest way I know of. Reading/writing text files and having to re-interpret them is just creating a pointless bottleneck in Lua.

 

I hope this is just a limitation of the Lua wrapper used in Java (or just Java itself) and not actually intentional.

Link to comment
Share on other sites

Depending on what you want to save you could use the moddata. Every object in PZ has its own moddata and since a few versions we can also store tables in it. I use it for example to store the lock levels for doors in my lockpicking mod.

 

I think limiting the file reading and writing is actually intentional.

Link to comment
Share on other sites

Is there somewhere I can read up on what all is available from Lua and what isn't?

 

If we have access to dostring() then I supposed we could just load a file as a string and use that. Just kind of seems silly to disable I/O if the only intention is security (I assume that's why). Since Lua is easily sandboxed, and all the functions can be overridden, you can easily replace parameters to control the paths...

local _io = ioorlocal _io.open = io.open... function io.open(path,mode)    -- do whatever you want with the path, return error if outside mod/lua directory, ect    return _io.open(path,mode)end

This way you can replace the original functions without having to rewrite it since the original one is only defined locally. And you have full control over the path.

 

There are valid reasons to allow the script to access any path too. For example if you are hosting more than one multiplayer server. If you can tell it to dofile() to a specific location then you can have all servers use the same scripts in whatever directory structure you want. Then you don't have to update all servers separately when you change something. This could also be server-only so that client mods can't access the file system, and server admins can control their own.

 

Some of the script systems I have developed for other games would get up to 3MB+ in size as it allows the freedom to create something as complex as you like. I was also hosting 10 different servers using the same scripts but running different maps and game modes. If I had to have the scripts separate that would be ten times the amount of data. At least in Linux you can use symlinks if you have to, but why make things more difficult than they need to be? I hope you can understand my concern.

Link to comment
Share on other sites

Kahlua is a Virtual Machine together with a standard library, all implemented in Java. It tries to emulate Lua as much as possible, while still reusing as much as possible from Java. Nothing has been cloned or ported directly from Lua, instead it's done by reverse engineering the features that exists in Lua, mostly by using the Lua reference manual and PiL as reference.

 

 

Well, that answers my question. Didn't realize it was using it's own interpreter instead of using the actual Lua interpreter. That definitely makes more sense. Sorry for wasting your time.

Link to comment
Share on other sites

  • 1 month later...

This function is in my include file.  It's a way to do a "Check if File Exists()".  If it returns nil, well... You know the routine by now :)

--prints an error message if file not exist in dir.  function checkFileExist(_sFile)     local string sFile = _sFile;    local file = getFileReader(sFile, false); -- dir: C:\Users\User\Zomboid\Lua     if file == nil then  --does anything exist there?        print("RAENBOW : Could not find file : ".. sFile .. " in C:\Users\User\Zomboid\Lua");    else        -do nothing.  File exists.    end end

So if you wanted to check a file existed in your code, the format of the function would be:

checkFileExist("Item_ m4a1.png");

The file extension doesn't matter in this very basic function.  Note the path I have commented actually, you'll see what RoboMat was saying- We aren't able to do what are known as i.o write/read from our wee lua files to anywhere except this directory.  

 

So any custom files we want people to be using have to be in 

 

C:\Users\User\Zomboid\Lua
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...