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

Listing folders in folders

Started by MarioBG, 17 January 2015 - 09:47 PM
MarioBG #1
Posted 17 January 2015 - 10:47 PM
Hello there, chaps!
Last evening, while finishing up my OS's Version 1.2 (1.1 was never released to the public), I ran into trouble when trying to make both the installer and the size-checking utility. While I can check file sizes no problem, I have troubles thinking of a function that can iterate over a filesystem and assess its size. I mean, I thought of the dirty solution of putting many loops one inside another, but that's just bad, and it limits the number of folders you can make.

As for the installer, what I can't see is the way to check the content of folders, and I think that, given a table which contained the needed data, I wouldn't know what to do with it either. This is a problem because I want to make a single-file installer, that needs no downloading multiple files from Pastebin or similar.

So, any ideas? Thanks in advance!
InDieTasten #2
Posted 17 January 2015 - 11:29 PM
you could do this simply with a recursive function:

function getRecursiveSize(path)
	local result = 0
	for k,v in pairs(fs.list(path)) do
		if(fs.isDir(path..v)) then
			result = result + getRecursiveSize(path..v.."/")
		else
			result = result + fs.getSize(path..v)
		end
	end
	return result
end
getRecursiveSize("/")
getRecursiveSize("/rom/")

the size won't include filenames and foldernames though.

it's just a function that sums all filesizes within the given folder, subfolder, subsubfolder… so I guess thats what you wanted right?
Edited on 17 January 2015 - 10:31 PM
Bomb Bloke #3
Posted 17 January 2015 - 11:47 PM
I've taken a liking to using a table to track progress, rather than recursing:

local fileList, output = fs.list(shell.resolve(".")), {}

while #fileList > 0 do
	if fs.isDir(shell.resolve(fileList[#fileList])) then
		local thisDir = table.remove(fileList,#fileList)
		local newList = fs.list(shell.resolve(thisDir))
		for i = 1, #newList do fileList[#fileList+1] = fs.combine(thisDir,newList[i]) end
	else output[#output+1] = table.remove(fileList,#fileList) end
end

"output" ends up containing the path to every file in the current folder and its subfolders.
MarioBG #4
Posted 18 January 2015 - 12:02 AM
you could do this simply with a recursive function:

function getRecursiveSize(path)
	local result = 0
	for k,v in pairs(fs.list(path)) do
		if(fs.isDir(path..v)) then
			result = result + getRecursiveSize(path..v.."/")
		else
			result = result + fs.getSize(path..v)
		end
	end
	return result
end
getRecursiveSize("/")
getRecursiveSize("/rom/")

the size won't include filenames and foldernames though.

it's just a function that sums all filesizes within the given folder, subfolder, subsubfolder… so I guess thats what you wanted right?
Thanks a lot! This will do very well for checking the size of the stuff.
I've taken a liking to using a table to track progress, rather than recursing:

local fileList, output = fs.list(shell.resolve(".")), {}

while #fileList > 0 do
	if fs.isDir(shell.resolve(fileList[#fileList])) then
		local thisDir = table.remove(fileList,#fileList)
		local newList = fs.list(shell.resolve(thisDir))
		for i = 1, #newList do fileList[#fileList+1] = fs.combine(thisDir,newList[i]) end
	else output[#output+1] = table.remove(fileList,#fileList) end
end

"output" ends up containing the path to every file in the current folder and its subfolders.
This, on the other hand, will do quite nicely to craft the table that powers the installer. I'd just have to include the actual content of the files in the table, and Bob's your uncle!

Thanks to both of you, and I hope to see you round checking my OS!
MarioBG #5
Posted 18 January 2015 - 11:28 AM
you could do this simply with a recursive function:
 function getRecursiveSize(path) local result = 0 for k,v in pairs(fs.list(path)) do if(fs.isDir(path..v)) then result = result + getRecursiveSize(path..v.."/") else result = result + fs.getSize(path..v) end end return result end getRecursiveSize("/") getRecursiveSize("/rom/") 
the size won't include filenames and foldernames though. it's just a function that sums all filesizes within the given folder, subfolder, subsubfolder… so I guess thats what you wanted right?
By the way, if any future user is to look at this topic for help, I had to modify this function a bit for it to fully work. The result is this:

function getRecursiveSize(path)
	    local result = 0
  if fs.isDir(path) then
   for k,v in pairs(fs.list(path)) do
	 if(fs.isDir(path.."/"..v) then
	   result = result + getRecursiveSize(path.."/"..v)
	 else
	   result = result + fs.getSize(path.."/"..v)
	 end
   end
  else
   result = fs.getSize(path)
  end
	    return result
end
Edited on 18 January 2015 - 10:29 AM
Dragon53535 #6
Posted 18 January 2015 - 10:57 PM
This question was asked a while ago, and i posted inside of it. After looking through quite a bit of my previous posts to find the correct thread. I present to you two coding options for finding a file's size:

Mine

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
This one gives you the total hard drives file space with the space of every folder's contents. Each folder is saved under folderSize["/rom"] or whatever, such that the path's only contain the total of the files that are in the folder.
When calling it, using

local total = findSpace()
Total is the total amount of space used by all the computer's folders.

[namedspoiler=KingofGamesYami's]
[CODE]
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
[/CODE]
[/namedspoiler]