Lua file:read unexpected behavior - file

I'm a complete newbie in Lua and i've stumbled upon a problem i don't understand.
So what i'm trying to do is open a file, read the data and save it into a different file with a different name.
Here is the code
local infile = io.open(folder..'/'..f, "r")
local instr = infile:read("*all")
infile:close()
local outfile = io.open(folder..'/'..newName, "w")
outfile:write(instr)
outfile:close()
The result i get is a Source file 288Kb and a Dest file 2Kb
So again, as i'm a newbie in Lua, the fact that the problem is in infile:read is a wild guess for me, but the way i see it, it's either infile:read or outfile:write.
UPD:
The content is absolutely arbitrary, which implies special symbols occur.
Thank you in advance,
Regards!

I've made it work by opening the in- and output file in binary mode by adding flag b in the io.open call., so the code I have now is
local infile = io.open(folder..'/'..f, "rb")
local instr = infile:read("*all")
Log(instr)
infile:close()
local outfile = io.open(folder..'/'..newName, "wb")
outfile:write(instr)
outfile:close()

Related

Read/Write highscore from a file (Lua - Corona SDK)

Here's my issue: I have a file with the highscore written in it (just the first line, no nicknames, just the highscore), I need to read that line and compare it with the actual score obtained in the game session, if the score is higher, overwrite the file with the new value, but if I try to read it I get a null value... Seems like i'm not reading it the right way. What's wrong with my code?
Thanks for the help!
local path = system.pathForFile( "data.sav", system.DocumentsDirectory )
local file = io.open( path, "w+" )
highscore_letta = file:read("*n")
print(highscore_letta)
if (_G.player_score > tonumber(highscore_letta)) then
file:write(_G.player_score)
end
io.close( file )
I had this problem myself. I found out that if you open a file in "w+" mode, the current contents are deleted, so that you can write new contents. So to read and write you have to open the file twice. First, you open the file in "rb" mode and get the file contents, then close it. Then you reopen it in "wb" mode, write the new number, and close it.
In Windows, you need "b" in the file mode. Otherwise, the strings that you are reading and writing may be modified in unexpected ways: for instance, a newline ("\n") may be replaced with carriage return–newline ("\r\n").
The file modes that Lua supports are borrowed from the C language. (I found a description on page 305 of what I guess is a draft of the C specification.) I think the Lua manual sort of assumes that you will know what these modes mean, as an experienced C programmer would, but to me it wasn't at all obvious.
Thus to read a number and then write a new one:
local filepath = "path/to/file"
-- Create a file handle that will allow you to read the current contents.
local read_file = io.open(filepath, "rb")
number = read_file:read "*n" -- Read one number. In Lua 5.3, use "n"; the asterisk is not needed.
read_file:close() -- Close the file handle.
local new_number = 0 -- Replace this with the number you actually want to write.
-- Create a file handle that allows you to write new contents to the file,
-- while deleting the current contents.
write_file = io.open(filepath, "wb")
write_file:write(new_number) -- Overwrite the entire contents of the file.
write_file:flush() -- Make sure the new contents are actually saved.
write_file:close() -- Close the file handle.
I created a script to do these operations automatically, as they're somewhat annoying to type every time.
The mode "r+" or "r+b" is supposed to allow you to read and write, but I couldn't get it to work when the original contents are longer than the new contents. If the original contents are "abcd", four bytes, and the new contents are "efg", three bytes, and you write at offset 0 in the file, the file will now have "efgd": the last byte of the original contents is not deleted.

Opening a file in C in write mode

I am writing a C program that converts a text file into a binary file and vice versa. The first question I have is about opening a file in "w" mode. Is there any need to have a check that the output file is opened correctly?
FILE *output;
output = fopen("output.bin", "w");
if(output == NULL)
{ printf("Error opening output file\n");}
Basically my question is whether or not output would ever actually == NULL. Because if there was a problem opening the output wouldn't it just create a new file named "output.bin"?
Also my other question is how characters are actually saved in a binary file. I know I'm supposed to save each character as an unsigned char so it can have values between 0 and 255 and then I should write that char to the output file. The actual logical path of how that happens is not making sense if anyone can help me or point me in the right direction I would appreciate it!
Yes, opening a file in write mode might still fail. Here's a bunch of possible reasons, but certainly not the only ones:
You don't have permission to create or change the file.
The file is read-only, or the directory it would be in is read-only.
The file would be inside another file. (test/foo if test is a file and not a directory)
The filesystem is out of space or inodes (on filesystems that have a fixed number of inodes)
The user has hit their disk space quota.
The file would be on another computer, and the network is down.
The filename is invalid - such as C:/???*\\\\foo on windows.
The filename is too long.

How to remove contents of the file when opened using r+ mode?

I've got my file open using r+ mode. I've made some alteration to it, and I would like to remove the contents of it starting from X to the end of the file.
Unfortunately I have no clue how to do that. I've been browsing through the docs, but there's no mention of that.
I don't want to write :space: to the file so it "looks" like it's cleared, I would like to make it smaller as well.
Opening the file using w is not an option in this case.
Opening a file with r+ mode preserves the current content; as the result, I don't think there is a way to truncate the rest of the file using the functions available in Lua. This SO answer indicates that it can be done using reopen with w+, but since you indicated that you can't open it for writing, I don't think there is a way to do what you want.
Testing on this script produces new contentext (where ext is the leftover from the earlier content):
local f = io.open("somefile", "w")
f:write("some long text")
f:close()
local f = io.open("somefile", "r+")
f:write("new content")
f:close()
Based on my experience, the only way I have found to truncate a file in Lua is to write the contents to a secondary file in "w+" mode, and then rename the secondary file to overwrite the original file. You will probably want to use this method sparingly depending on the size of the file, of course.
In this example "path" is the path to the original file
local file, err = io.open( path + ".tmp", "w+" )
if not file then return end
file:write( truncated_data )
file:close( )
assert( os.rename( path + ".tmp", path ) )

Lua file reading and writing error

Sorry if there's already a topic like this, but I couldn't find any that have something to do with Lua... So I'm basically having some problems in writing and reading files, here's what I've done:
hp = 25
file = io.open("player.txt","w")
if file==nil then
io.output("player.txt")
io.close()
end
file:write(hp)
file:close()
and it seems to work fine, it's just perfect... but then when I'm trying to add the file:write(hp) inside the if-sentence, it doesn't work. Also if I'll add file:read("*line") right after file:write(hp), this is what it says in player.txt:
25b[NUL]ÈñZ[NUL]
file = io.open("player.txt","w")
So what am I doing wrong? Also [NUL] is black block with white "NUL" text in it in notepad++ but it can't be copied here.
Edit: Hmmh, seems like the whole code is messed, up it always rewrites the whole file ;o
Edit2: Had actually no idea what I was talking about, nowadays I can understand file controlling bit more, here's what it should've been or what I tried to do:
function existsFile(path)
x = io.open(path)
if x == nil then
io.close()
return false
else
x:close()
return true
end
end
if not existsFile("player.txt") then
file = io.open("player.txt", "w")
file:write(25)
hp = 25
file:close()
else
file = io.open("player.txt", "r")
hp = file:read("*number")
file:close()
end
And I know it doest look anything like the code I first posted, but that's what I basically meant.
Could you explain what you are trying to do in this code?
Why do you need to check if file is nil? When you open file for writing, lua automatically creates it if not exists.
"w" mode means, that you you're erase all data in file and write new data
May be you need "a" mode? In this mode new lines are added at the end of file.
Sounds like you're confused about the flags on io.open. Check the manual to be sure what you really want is the w flag since that overwrites everything.
Trying to do a file:write when you're in the if shouldn't work, and I'm not sure why you'd expect it to, since file is nil. You're saying that if the file couldn't be opened, then try to write this to the file, which doesn't make sense to me.
The "if" block checks if "file" is nil, so that code block will never run.
read() doesn't work because you opened the file in "w" (write) mode.
Erasing the whole file is the expected behavior of write mode. In that mode the file is first erased and then you write new data to it.

C Programming fopen() while opening a file

I've been wondering about this one. Most books I've read shows that when you open a file and you found that the file is not existing, you should put an error that there's no such file then exit the system...
FILE *stream = NULL;
stream = fopen("student.txt", "rt");
if (stream==NULL) {
printf(“Cannot open input file\n”);
exit(1);
else {printf("\nReading the student list directory. Wait a moment please...");
But I thought that instead of doing that.. why not automatically create a new one when you found that the file you are opening is not existing. Even if you will not be writing on the file upon using the program (but will use it next time). I'm not sure if this is efficient or not. I'm just new here and have no programming experience whatsoever so I'm asking your opinion what are the advantages and disadvantages of creating a file upon trying to open it instead of exiting the system as usually being exampled on the books.
FILE *stream = NULL;
stream = fopen("student.txt", "rt");
if (stream == NULL) stream = fopen("student.txt", "wt");
else {
printf("\nReading the student list directory. Wait a moment please...");
Your opinion will be highly appreciated. Thank you.
Because from your example, it seems like it's an input file, if it doesn't exist, no point creating it.
For example if the program is supposed to open a file, then count how many vowels in it, then I don't see much sense of creating the file if it doesn't exist.
my $0.02 worth.
Argument mode:
``r'' Open text file for reading.
``r+'' Open for reading and writing.
``w'' Truncate file to zero length or create text file for writing.
``w+'' Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated.
``a'' Open for writing. The file is created if it does not exist.
``a+'' Open for reading and writing. The file is created if it does not
exist.
Your question is a simple case. Read above description, when you call fopen(), you should decide which mode shall be used. Please consider why a file is not created for "r" and "r+", and why a file is truncated for "w" and "w+", etc. All of these are reasonable designs.
If your program expects a file to exist and it doesn't, then creating one yourself doesn't make much sense, since it's going to be empty.
If OTOH, your program is OK with a file not existing and knows how to populate one from scratch, then it's perfectly fine to do so.
Either is fine as long as it makes sense for your program. Don't worry about efficiency here -- it's negligible. Worry about correctness first.
You may not have permission to create/write to a file in the directory that the user chooses. You will have to handle that error condition.

Resources