Snippet: Load file in binary, to Lua table -- 1 byte per entry (string

This function prompts for a user chosen file and returns a table of that files bytes. One byte per table entry. The bytes are stored as strings in this example, so they can be printed as hex numbers.

This code can be run in testpad and will rprint the table (i.e. the file contents) to the terminal:

--[[ Function to read a user chosen file into a Lua table. The table is populated 
one hex byte to one entry i.e. {0A,56,22,FF,...}--]]

--parameters:
--(file_types) is a table of file types to load,
--(dialog title) is the title for the standard GUI loader
--returns: table or nil
local function load_file_in_bytes_to_table(file_types,dialog_title)
------------------------------------------------------------------------------------ 
  ----------------------------------------------------------
 --Helper to convert file stream stringbytes to "hex" format
 ----------------------------------------------------------
 local function num_to_hex_string(num)

 num = tonumber(num)
 if num == nil then
 return
 end
 --format to 2 digits hex and return 
 return string.format("%02X",num)
 end
  
  --------------------------------------------------------------------------------
  --read the user supplied file and put it byte by byte into a table using Lua io. 
  --------------------------------------------------------------------------------
  --create table to return
  local file_bytes = {}
  
  --get file path
  local file_in = renoise.app():prompt_for_filename_to_read(file_types,dialog_title)
  
  --check if file path returned
  if file_in == "" then
    return nil
  else 

    --incrementor so we can loop through whole file
    local inc = 1 
    ----------------
    -- //Lua io.//
    ----------------
    -- io.open(),opens a file -- needs to be called whether you are reading or writing to a file
    --"rb" indicates "read binary mode"
    -----------------------------------
    local file = assert(io.open(file_in,"rb"))   

    --loop through the file 1 byte at a time 
    while true do
      ---------------
      --//Lua io.//--
      ---------------
      --read the file 1 byte at a time
      ---------------------------------
      local current_byte = file:read(1)
           
      --if bytes exist continue looping
      if current_byte ~= nil then
        --convert string to bytes with the Lua string.byte()function
        current_byte = string.byte(current_byte)
        --add byte to table using num_to_hex_string()
        file_bytes[inc] = num_to_hex_string(current_byte)
        ---------------
        --//Lua io.//--
        ---------------
        --increment file stream pointer along the file
        --"set" means the `inc` offset is counted from file start ("cur" and "end" can be used as alternatives here)
        ---------------------
        file:seek("set", inc)
        --increment for next time round (used for `file_bytes` and file:seek)
        inc = inc + 1 
        
      else
        --break the loop as there are no more bytes in the file
        break
      end
    end   
  end
  return file_bytes  
end --of load file in bytes to table

--run above function and rprint returned table. If no file is loaded then nil will be printed
----------------------------------------------------------------------------------------------
rprint(load_file_in_bytes_to_table({"."},"Choose Any File"))

Suggestion: this part

--hex format  
num = string.format("%X",num)
--add leading zero then return
if #num < 2 then
  return tostring("0"..num)
end

could be changed to a single statement

num = string.format("%02X",num)
  • seems like an easy optimization :slight_smile:

Updated thanks!

I wasn`t aware of that extended formatting.

We are both quite seasoned lua hackers, but I’ve found that the following cheat sheet has helped me immensely:

https://github.com/Strewya/engine/blob/master/docs/luarefv51single.pdf

And yes, especially with the formatting stuff :slight_smile:

That looks a bit familiar, I think I printed something like that off when I was first learning Lua.

It looks pretty handy though and I think I`ll be better able to to figure out what it all actually means now! :slight_smile:

thanks for the link