This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
BigSHinyToys's profile picture

Method of reading a file as data table or string withour error corection

Started by BigSHinyToys, 09 April 2012 - 07:15 AM
BigSHinyToys #1
Posted 09 April 2012 - 09:15 AM
A function that reads a file to a data table compatible with bit API or a way to read a string with out the computer correcting unknown symbols into "question marks".

reasons why

1) Cant really call a program a FTP if it can only handle test/lua files
2) encrypted files would be corrupted when sent over rednet by auto correction.
3) file compression like zip would be able to be used over rednet

I was going to post this in bugs as file.readAll() causes this but further research made me release it was reacting correctly from a string perspective in correcting the supposed errors.

the bellow program will demonstrate how files are altered on read by file.readAll() witch is the only way to read a file in the context of rednet messaging. As fs.copy only works locally

Instructions
place both test.lua and pic.png in the root of a computer.
run test.lua
http://www.filefactory.com/file/5darm4i55gl5/n/test_zip
Hawk777 #2
Posted 09 April 2012 - 10:58 AM
There are two problems here:
  • You're opening the file wrong. Where you pass "r" or "w" as the mode to "fs.open", you need to pass "rb" or "wb". Opening binary files in text mode will not work right. Please see the fs.open wiki page for details. I changed your code to the following and it makes a perfect copy of the file (note that this code still puts the contents of the file into a string; this proves that the fault does not lie with strings or files):
  • 
    -- Demonstration program showing data alteration
    -- By Big SHiny Toys for Computer Craft Froums
    
    term.clear()
    term.setCursorPos(1,1)
    print("file pic.png will be read in as string and saved as pic2.png  I am not using fs.copy() as im demonstrating what happens over rednet")
    write("Do you want to continue y/n : ")
    while true do
    	e,e1 = os.pullEvent()
    	if e == "char" and e1 == "y" then
    		print("y")
    		break
    	end
    	
    	if e == "char" and e1 == "n" then
    		print("n")
    		return
    	end
    end
    
    if fs.exists("/pic.png") then
    	print("Opning File for read")
    	
    	file = fs.open("/pic.png","rb")
    	local tHolding = {}
    	local bTemp
    	repeat
    		bTemp = file.read()
    		if bTemp ~= nil then
    			table.insert(tHolding, bTemp)
    		end
    	until bTemp == nil
    	local sHolding = string.char(unpack(tHolding))
    	file.close()
    	
    	print("File read in")
    	print("saving")
    	
    	file = fs.open("/pic2.png","wb")
    	for i = 1, sHolding:len() do
    		file.write(sHolding:byte(i, i))
    	end
    	file.close()
    	
    	print("saved")
    else
    	print("Please place test.lua and pic.png in the root of a computer")
    	print("then retry program")
    	print("Program ended")
    end
    
  • Though your sample code doesn't show it, you mention RedNet. It's not possible to transport arbitrary binary data over RedNet, neither through bundled cables nor through modems, despite that data being represented properly in a string. This is because modems are not binary-safe (and neither is bundled cable). If you want to transport binary data from one computer to another via RedNet, you'll need to encode it somehow (Base64 or BinHex would be suitable starting points, though something that spreads the bits into a 7:8 expansion would be more efficient).