Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Copying folders 5

Status
Not open for further replies.

gwar2k1

Programmer
Apr 17, 2003
387
GB
I have script to copy single files but I need a script to copy whole directories. Does any one know how this can be achieved?

Here's the code I have at the moment:

assign(source,main); {the file to be copied is assigned a path passed by reference}
assign(dest,backup); {where the file is copied to is defined in the procedure}
reset(source,1); {opens the file at the begining and sets the number of records to 1}
rewrite(dest,1); {creates a new file with one record}
getmem(buffer,1024); {gives the pointer (buffer^) 1024 bytes of memory}
REPEAT {until size of data being read is < 1Kb}
blockread(source,buffer^,1024,actually_read);
blockwrite(dest,buffer^,actually_read,written);
UNTIL actually_read < 1024;
close(source);
close(dest);
writexy(3,48,'File copied :: <return>');
readln;

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Two points:

(1) I am only suggesting keeping a list of directories that have yet to be copied, not a list of files. I am not suggesting keeping it anywhere in particular. Heap would be ideal, but if you really like mega-drives and want to copy the world, keep the list on disk! I am deeply sceptical that you will ever copy a directory structure so complex that you can't keep this information in memory. It's not a lot.

(2) I cannot see any earthly reason why working in real mode should prevent you from keeping a list. Anyone care to explain?

(3) I am also sceptical about the effect of buffer size on speed. Abrash gives figures for this, and they agree with my rough guesses from experience: on virtually no machine do you get noticeable gains beyond a few K. You have to remember that disk reads are already buffered at several levels anyway.

But I can't definitively disagree with LorenPechtel's statement that the routine as posted is slow since I haven't typed it in and measured it.
 
Oh, lists versus recursion:
If you select the recursive approach, what do you think the stack is? It's just a list of directories you haven't yet done, interspersed with copies of the address of your search routine...

By the way, has anyone noticed the way this site awards stars automatically to each posting made by a previously starred poster? Seems a bit silly, really. I mean, I might write something sensible in one post and follow it with something highly star-unworthy!
 
Im taking the recursive approach first. You only over come fears if you face them right? lol. Im gonna use an array for it, dump names in the array etc. Or when you talk about the stack do you literally mean the stack ie PUSH and POP?

I think if youre awarded a star in a thread it appears by your name for every post you make after it but you are still only awarded 1 star. Ive given what 5 stars to ppl cause their posts really are helpful (state what needs doing and why the solution does what is asked of it) and its the only recognition I can give

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
If you use a pointer to a list as only local variable in a NEAR procedure and the two string parameters are pointers, you can go +/- 64 levels deep with a stack of 1024 bytes (return address = 2 bytes, PUSH BP = 2 bytes, 2 parameters = 8 bytes, list = 4 bytes). 64 levels of DOS 8.3-rule directory names results in paths of minimal 131 and maximum 835 characters whereas the maximum path length including filename is 68 characters in DOS.
I assume you're working in DOS, so using recursion shouldn't be any problem. It is true, however, that there is a small possibility that the names of all the files to be copied won't all fit in heap memory, in that case, you can expand your list abstraction with a disk buffer.
With a heap of 256K and a singly linked list with 13 bytes for a filename, you can store +/- 16000 filenames and that's quite a lot for one directory.

Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
what about stack size? i dont normally play with the $M command. should i just set it to maximum?

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Like I said, a stack of 1024 should suffice: {$M 1024,<min heap size>,<max heap size>}

Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
I feel strongly you should be very cautious about increasing stack size to cater for recursive routines. The problem is that if it works OK now by increasing the stack size, then in three years time when someone uses your utility on a directory structure that is twice as deep, it suddenly won't work any more. You really want a good margin of safety.

BertV is basically right: provided you are a little careful about what you save, there won't be a problem. Anyway, the default Pascal stack is 16K, so you'll have to go it some to fill that.

It doesn't really matter here, but in a pascal unit, if you declare a procedure or function in the interface section so that other units can see it, it is automatically far called, which can make things less efficient in recursion. In this sort of case I often declare a boring procedure in the interface section, which then calls my entirely near, local procedure to do all the work.

gwar2k1, yes, I did mean the stack in the sense that BertV used it. A recursive procedure is just keeping multiple levels of data in the stack segment, because each time it calls itself, a new set of local variables and parameters are set up on the stack, so the stack becomes a list of instances of those variables. The up-side is it's easier to program than a list. The down-sides are that (a) the stack is more size-limited than the heap, and (b) you not only establish new instances of variables you need, you also repeat all the &quot;start of procedure&quot; code, and store return-addresses and things, which you might not want to do.
But having said that, when you call a recursive routine from itself, hopefully it's a near call. If you use getmem and freemem to manage list items, it's a far call, so if you use a list in a time-critical place, it's worth thinking about, too.

Thanks for the explanation of stars!
 
The reason I said you couldn't keep the list in real mode is that you would run out of memory. I have written a fancier version of this (1500 lines of code none of which is devoted to asking the user anything). I've seen files copied well past 100,000, I've seen directories in excess of 50,000. A script to back up the stuff that needs backing up, results: It looked at almost 14,000 files and nearly 1000 directories.

As for buffer speed--if the drive reads ahead enough it might not matter much. However, you are still making extra OS calls. *LONG* ago I was lazy in writing a routine--I needed to read a text file to the screen. Repeat Read(Source, Ch); Write(Ch); Until IOResult <> 0; It got used when the file being read was on a server. It looked like about 4800 baud!
 
Hehe no problem, thanx for all the pascal help people!

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top