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

fs.getSize("/") isn't working correctly

Started by Techman749, 30 October 2014 - 07:17 PM
Techman749 #1
Posted 30 October 2014 - 08:17 PM
Hello ComputerCraft Community!

I've been writing the control panel program for my OS, and I was making a general information tab inside the control panel, and one of the functions of the general info tab was to display:
> space remaining
> total space used
> total size of system folder, apps folder, and user folder.

I decided the test the API by going into the lua program in CraftOS and entering:

fs.getSize("/") – supposed to return the size of the entire drive

But when I enter this into the program it returns "0" when I know for a fact it's not 0 bytes because I have 128kb work of files in there.

Full code:
local default = 5242880
local size = fs.getSize("/")
local result = default - size
return result

It then returns the default size because it's not subtracting the difference (it's subtracting "0" because fs.getSize("/") is returning "0")

Any recommendations are gladly accepted!

Thank you for your time reading this!
Dragon53535 #2
Posted 30 October 2014 - 08:24 PM
fs.getSize doesn't work with directory, only files. So your best bet would be to get the size of EVERY file through a recursive function that searches through the directories.
Techman749 #3
Posted 30 October 2014 - 09:09 PM
So I'm going to have to use some type of wildcard function to get the size of every file in a directory?

Like if I tell it to get the size of a folder,I'll have to make it get the size of every file, and if it finds a folder make it go into the folder and get the size of every file in there? And then make it add all of the sizes it found?

It doesn't sound to hard of a function to code, but I wish dan could make that function available in the fs API. Doesn't fs.getFreeSpace("/") do something similar?
Dragon53535 #4
Posted 30 October 2014 - 09:24 PM
I do believe that it gives the full space available, so if you know the max then you could subtract that to get the used. However to get the total size of a certain folder, you'd need a function that goes into them all.
Emma #5
Posted 30 October 2014 - 10:25 PM
I concur with Dragon53535, in that you need to call that function on every file, this can be done very simply with a recursive file lister.
First we need to create a table with which we will keep track of the files we've listed so far, lets call it files and put it inside a function.

function listAll(startdir, files)
  files = {}
end
When you first call it, files will be empty so we don't need to supply it with {}, but in other times it won't be so we cant assign it an empty table, so we can just do a nil check empty instigator.

files = files or {}
Then we need to get a list of all the files in that directory, so we do this:

local dlist = fs.list(startdir)
Then we loop through those, and if its a directory call the function with the original file listing, if its a file then add it to the table.

for i=1,#dlist do
  local path = fs.combine(startdir,dlist[i])
  if fs.isDir(path) then
	listAll(path,files)
  else
	table.insert(files,path)
  end
end
Then we just return the table.

return files
Here is the final code:
Spoiler

function listAll(startdir,files)
  files = files or {}
  local dlist = fs.list(startdir)
  for i=1,#dlist do
	local path = fs.combine(startdir,dlist[i])
	if fs.isDir(path) then
	  listAll(path,files)
	else
	  table.insert(files,path)
	end
  end
  return files
end
KingofGamesYami #6
Posted 30 October 2014 - 10:41 PM
You can't use fs.getFreeSpace?
Dragon53535 #7
Posted 31 October 2014 - 12:44 AM
I actually wrote a snippet of code for you that gives you a variable and table, the table holds the space for each directory, with the full path, and the space that directory consumes, and then a variable is returned with the total space used. As i'm in class right now i cannot access it right now however when i get home i will edit this post to add the code i made for you.
KingofGamesYami #8
Posted 31 October 2014 - 12:52 AM
@Dragon:
Does it look something like this?

local function getSize( path )
  if not fs.isDir( path ) then
    return fs.getSize( path )
  end
  local s = 0
  for k, v in ipairs( path ) do
    s = s + getSize( fs.combine( path, v ) )
  end
  return s
end
Techman749 #9
Posted 31 October 2014 - 01:51 AM
Thank you for your example code, incinirate! If I use it I'll credit you for it in the OS!

To answer your question, KingOfGamesYami, yes, I could use that function, but I'm wanting to get the total size of the "hard drive". And there isn't a function is the fs API (to my knowledge) that does that.

Unless I know what the size of the computer is set to in the computercraft.cfg file, I have no idea of knowing what the total size is.So I can't subtract what fs.getSize("/") (or the new function incinirate showed me.) returns from the total size, because I don't know what the total size is. Like if I'm on a server, the admin probably won't know where to find this info, and besides, I dont want to modify my OS every time I go on a different server, so I'm wanting to make it to where the OS detects the total size.

Maybe I'll make a suggestion to Dan to add this function to the FS API, it doesn't sound to hard to implement.
Dragon53535 #10
Posted 31 October 2014 - 03:05 AM
Really? You can get the total space by adding together the free space and the space used.

Also my code
Spoiler

local folderSize = {}
local function findSpace(path)
  local path = path or "/"
  local folderTotals = 0
  local fileTotals = 0
  if not fs.isDir(path) then
    path = fs.getDir(path)
  end
  for a,v in pairs(fs.list(path)) do
    if fs.isDir(fs.combine(path,v)) then
	  folderTotals = folderTotals + findSpace(fs.combine(path,v))
    else
	  fileTotals = fileTotals + fs.getSize(fs.combine(path,v))
    end
  end
  folderSize[path] = fileTotals
  return folderTotals + fileTotals
end
Yami's however is superior. However mine gives you the total space of all files, and the individual folder's path and space.

folderSize = {} --#Empty the folderSize table so that the space can be rewritten.
local total = findSpace() --#Total is now the total space of everything on the computer.

--#This makes it so that folderSize["/rom/programs"] is something and folderSize["/rom"] Is something else, yet doesn't contain the amount that the others do.