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

[help] file system api

Started by cheekycharlie101, 25 October 2012 - 08:43 PM
cheekycharlie101 #1
Posted 25 October 2012 - 10:43 PM
ok so im making a disk manager. so far ive made a nice program that:

checks for a drive
if the drive is found it checks for a disk.
if a disk is found it asks you to label the disk
once labeld it chucks it out.
may seem simple but took me ages, the code is in my forum signature.
anyway i wanna expand it to do other things. one of them includes cloning a disk. i think i will need to use os.pullEvents to fire when a disk is removed and enterd. but i dont know how it would copy all the contents over. if someone could give me an idea or point me in the right direction i would be really thankful.
thanks -Cheeky
Beardmoresam #2
Posted 25 October 2012 - 11:41 PM
I don't know much about it, but I believe that there is some syntax for it on the wiki.
My guess is you have to first tell the computer that you want to address the disk directory, not the rom/whatever else, then within the disk, address whatever file it is you are after and simply copy it over to the computers own directory.
But I may be completely wrong, after all that is just a thought I had.

EDIT– A quick look on the wiki gave me this: http://computercraft.info/wiki/index.php?title=Fs_%28API%29
I think that should do the trick.
KillaVanilla #3
Posted 26 October 2012 - 01:18 AM
Use fs.copy:

fs.copy(oldFile, newFile)

Also, here's a little snippet of code that might help:

local function getDrive(driveNumber)
if driveNumber >= 1 and driveNumber <= 6 then
  local search = "disk"
  if driveNumber > 1 then
   search = search..tostring(driveNumber)
  end
  for i,v in ipairs(rs.getSides()) do
   if peripheral.isPresent(v) and peripheral.getType(v) == "drive" and disk.getMountPath(v) == search then
    return v
   end
  end
end
end
It takes a drive number (1-6, or "disk" to "disk6") and returns what side that drive's mounted on.
cheekycharlie101 #4
Posted 26 October 2012 - 09:47 AM
Use fs.copy:

fs.copy(oldFile, newFile)

Also, here's a little snippet of code that might help:

local function getDrive(driveNumber)
if driveNumber >= 1 and driveNumber <= 6 then
  local search = "disk"
  if driveNumber > 1 then
   search = search..tostring(driveNumber)
  end
  for i,v in ipairs(rs.getSides()) do
   if peripheral.isPresent(v) and peripheral.getType(v) == "drive" and disk.getMountPath(v) == search then
	return v
   end
  end
end
end
It takes a drive number (1-6, or "disk" to "disk6") and returns what side that drive's mounted on.

fs.copy is good, but i need to to copy an entire disk? i can think of no way of it checking for each file and copying it but im sure is possible
ChunLing #5
Posted 26 October 2012 - 10:25 AM
fs.list() returns a table that contains all the directories and files in a given path. You can crawl this table with a for i = 1,#fs.list("path") do … end loop.
KaoS #6
Posted 26 October 2012 - 10:30 AM
ok, try this


for k,v in pairs(fs.list('disk')) do
  fs.copy('disk/'..v,'disk2'..v)
end

or copy them to a temporary folder and then to the next inserted disk. meh

EDIT: lol ninja'd
ChunLing #7
Posted 26 October 2012 - 10:37 AM
Hehehe. The fs.list return is sequential, so using in pairs isn't necessary if you store the table (which I neglected to do). You can also make this a recursive function, so that it can find subdirectories.
KaoS #8
Posted 26 October 2012 - 12:10 PM
Indeed, I just prefer using pairs cos then you have a variable rather than having to access a table every time and you don't have to save the table

EDIT: recursive functionality


local function copydisk(path)
  local path=path or ''
  for k,v in pairs(fs.list('disk'..'/'..path)) do
    if fs.isDir(v) then
	  copydisk(path..'/'..v)
    elseif fs.exists('disk/'..path)
	  if not fs.exists('disk2/'..path) then fs.makeDir('disk2/'..path) end
	  fs.copy('disk/'..path..'/'..v,'disk2/'..path..'/'..v)
    end
  end
end
cheekycharlie101 #9
Posted 26 October 2012 - 04:35 PM
ok, try this


for k,v in pairs(fs.list('disk')) do
  fs.copy('disk/'..v,'disk2'..v)
end

or copy them to a temporary folder and then to the next inserted disk. meh

EDIT: lol ninja'd
ok so this copy's the contents of a disk to a folder called disk2 right?
KaoS #10
Posted 26 October 2012 - 05:31 PM
exactly. it makes a table of all of the contents and executes the copy command for every value in the list

please note that it does not copy the contents of folders, you need the second script for that
ChunLing #11
Posted 26 October 2012 - 07:46 PM
Lovely stuff there. I'd completely forgotten about that "= n or "something"" trick, I've got to start using it because it's a good trick.
cheekycharlie101 #12
Posted 26 October 2012 - 07:49 PM
exactly. it makes a table of all of the contents and executes the copy command for every value in the list

please note that it does not copy the contents of folders, you need the second script for that

Thanks, il begin working on this very soon. just another question? can you give me some help on the script for folders?, im still trying to get my head round the fs api.
thanks -Cheeky
KaoS #13
Posted 26 October 2012 - 08:04 PM
Indeed, I just prefer using pairs cos then you have a variable rather than having to access a table every time and you don't have to save the table

EDIT: recursive functionality


local function copydisk(path)
  local path=path or ''
  for k,v in pairs(fs.list('disk'..'/'..path)) do
	if fs.isDir(v) then
	  copydisk(path..'/'..v)
	elseif fs.exists('disk/'..path)
	  if not fs.exists('disk2/'..path) then fs.makeDir('disk2/'..path) end
	  fs.copy('disk/'..path..'/'..v,'disk2/'..path..'/'..v)
	end
  end
end

this should work
ChunLing #14
Posted 26 October 2012 - 08:07 PM
The function checks if the string in the table returned by fs.list() is a directory. If it is, then the function calls another iteration of itself to deal with the contents of that subfolder. When that subfolder is copied, that iteration of the function terminates and the first iteration continues where it left off, copying any other files.

Because function can only call itself for as many levels as there exist subfolders, this is a safe usage of recursion.
Cloudy #15
Posted 26 October 2012 - 09:02 PM
You do know that the copy function is recursive anyway?
KaoS #16
Posted 26 October 2012 - 09:04 PM
nope, wow…. you guys think of everything :D/>/> +1
ChunLing #17
Posted 26 October 2012 - 10:38 PM
Heh…did not know that. I thought it was only for copying individual files (that's the only way I've used it). I guess it does say that it copies directories, we should check the documentation more often.
cheekycharlie101 #18
Posted 27 October 2012 - 09:03 AM
Thanks sooooooo much for all the help. the thing i love about these forums is the ammount of support your receive. and it happens really quickly. THANKS SOO MUCH :D/>/>
cheekycharlie101 #19
Posted 30 October 2012 - 09:39 PM
Indeed, I just prefer using pairs cos then you have a variable rather than having to access a table every time and you don't have to save the table

EDIT: recursive functionality


local function copydisk(path)
  local path=path or ''
  for k,v in pairs(fs.list('disk'..'/'..path)) do
	if fs.isDir(v) then
	  copydisk(path..'/'..v)
	elseif fs.exists('disk/'..path)
	  if not fs.exists('disk2/'..path) then fs.makeDir('disk2/'..path) end
	  fs.copy('disk/'..path..'/'..v,'disk2/'..path..'/'..v)
	end
  end
end

this should work
doesent work, line 7 then expected even though there is one o_O
Cranium #20
Posted 30 October 2012 - 09:49 PM
elseif fs.exists('disk/'..path) needs to have a then at the end of it.
cheekycharlie101 #21
Posted 30 October 2012 - 09:57 PM
elseif fs.exists('disk/'..path) needs to have a then at the end of it.
thanks
cheekycharlie101 #22
Posted 30 October 2012 - 10:04 PM
elseif fs.exists('disk/'..path) needs to have a then at the end of it.
could you explain how to do this the other way around? so copy the contents from disk2 to disk?
thanks so much -Cheeky
cheekycharlie101 #23
Posted 30 October 2012 - 10:39 PM
ok guys, ignore my last 2 posts asking you to help me make it do vice versa as i know i shouldn't expect people to code for me. anyway i have made some code and it all works accept for the last part. it copies the stuff from the disk to the comp. ejects the disk asks for a new one. detects when a new disk is put it and while its pasting it i get 14:access denied. cant figure this out but when i tried running the program that i made that copies the files from the comp to the disk it worked. so i can figure out wat is wrong. here is my code. you may have to run it ingame to figure out all the steps as it is a little messy.

Spoiler

fs.delete("disk2")
write("Please Enter Drive Side: ")
local a = io.read()
  if a == "top" or a == "bottom" or a == "left" or a == "right" or a == "front" or a == "back" then
	print("Checking for drive...")
	 local b = peripheral.isPresent(a)
	 local c = disk.isPresent(a)
		local function copydisk2(path)
  local path=path or ''
  for k,v in pairs(fs.list('disk2'..'/'..path)) do
		if fs.isDir(v) then
		  copydisk(path..'/'..v)
		elseif fs.exists('disk2/'..path) then
		  if not fs.exists('disk2/'..path) then fs.makeDir('disk/'..path) end
		  fs.copy('disk2/'..path..'/'..v,'disk/'..path..'/'..v)
		end
  end
end
		local function copydisk(path)
  local path=path or ''
  for k,v in pairs(fs.list('disk'..'/'..path)) do
		if fs.isDir(v) then
		  copydisk(path..'/'..v)
		elseif fs.exists('disk/'..path) then
		  if not fs.exists('disk2/'..path) then fs.makeDir('disk2/'..path) end
		  fs.copy('disk/'..path..'/'..v,'disk2/'..path..'/'..v)
		end
  end
end
		   local function dcopy()
			 print("Scanning Disk...")
			 sleep(1)
			 print("Copying Disk...")
	copydisk()
			 print("Disk Copied.")
			 disk.eject(a)
	print("Please Enter New Disk")
	while true do
	  sleep(1)
	  if c then
	 print("New Disk Found")
	 sleep(1)
	 print("Pasting Disk...")
	 copydisk2()
	 sleep(1)
	 print("Disk Pasted")
	 disk.eject(a)
	 fs.delete("disk2")
	 break
	end
	end
			end
			
	   if b then
		 sleep(1)
		 print("Drive Found")
		 print("Checking for Disk...")
		   if c then
			 sleep(1)
			 print("Disk Found")
			 dcopy()
		   else
			 sleep(1)
			 print("No Disk Found")
		   end
	   else
		 sleep(1)
		 print("No Drive Found")
	   end
else
   print("Invalid Drive Side")
end
if you guys could tell me where im going wrong i would be really greatful.
thanks -Cheeky
–EDIT–
i belive its line 14 where its trying to make a directory called disk and it cant. if your wondering how i got this code i just took kaos's original code and swapped all the disk and disk2 parts around. il try figure this out but any help would still be apreciated.
thanks again -Cheeky
cheekycharlie101 #24
Posted 30 October 2012 - 11:36 PM
OK I DID IT!!! Its finshed and it works awesome, i managed it. if you wanna see the finished code click the diskmanager3.0 link in ma signature :DDDDD
im mega happy