Copying all Files with New Name

H

Hawksury Gear

Hi,
This forum has already been very helpful , Many Thanks.

Problem: I actually want to copy the contents of all files that is in a
particular directory into a new directory.The new files should be of a
specific size (2MB)and each with a new name (randomly assigned).

My Current Code looks,

require 'ftools'
testdir = "K:/test"
# Iterating over each entry
Dir.entries(testdir).each do |file|

# Joining the path where the files are

path = File.join testdir, file
if File.file? path

File.open path
File.copy(file,'K:/t1') # NOTE: t1 file doesn't exist assuming
will create itself? probably wrong

end
end
end

When simply trying to copy using File.copy(to,from) it gives following
error message "No such file or directory K:/"

Do you think this approach is completely wrong and I should try
creating File.new and reading every single line and copying over?

Any suggestions about giving random names for the new files..?

Many Thanks,
 
K

Kendall Gifford

Problem: I actually want to copy the contents of all files that is in a
particular directory into a new directory.The new files should be of a
specific size (2MB)and each with a new name (randomly assigned).

My Current Code looks,

require 'ftools'

I recommend using 'fileutils' instead. From the ftools docs:
"FileUtils contains all or nearly all the same functionality and more,
and is a recommended option over ftools"
testdir =3D "K:/test"
# Iterating over each entry
Dir.entries(testdir).each do |file|

Okay within this context you'll probably need to "filter out" or
ignore the "." and ".." entries. They show up in windows too.

Dir.entries(testdir).reject { |d| %w{. ..}.include?(d) }.each do
|file| # example removes . and ..

# Joining the path where the files are

=A0 path =3D File.join testdir, file
=A0 if File.file? path

=A0 =A0 =A0 =A0 =A0File.open path

You don't need to "open" the file to copy it, whether you're using
ftools *or* fileutils. I'd nuke the "File.open path" line.
=A0 =A0 =A0 =A0 =A0File.copy(file,'K:/t1') # ...

This is likely failing when you're trying to copy directory entries
"." and ".." which expanded would look like:

File.copy('K:/test/.', 'K:/t1')

However, if you filter out these entries beforehand then this should
work. Also note that it *will* create 'K:/t1' if it doesn't exist and
will also overwrite it if it does (unless there is a
permissions/access issue). The fileutils equivalent would be:

FileUtils.cp(file, 'K:/t1')
=A0 end
=A0 end
=A0end

Is it just me? I think I cound 1-too-many "ends" there.
When simply trying to copy using File.copy(to,from) it gives following
error message "No such file or directory K:/"

Again, I suspect this is because of the "." or ".." entry being
"copied". File.copy only allows the source to be a file, not a
directory (or so it appears).
Do you think this approach is completely wrong and I should try
creating File.new and reading every single line and copying over?

No need to use File.new. File.copy or FileUtils.cp do this for you just fin=
e.
Any suggestions about giving random names for the new files..?

If you're not worried about race conditions here is a simple version
from one of my old projects.

def unique_filename(location, basename =3D '', extension =3D nil, digits =
=3D 4)
extension =3D extension ? ".#{extension}" : ''
index =3D 0
namer =3D lambda { "#{basename}#{index.to_s.rjust(digits, '0')}#{extensio=
n}" }
name =3D namer.call
while File.exists?(File.join(location, name))
index +=3D 1
name =3D namer.call
end
File.join(location, name)
end

#
# Example Usage:
#
require 'fileutils'
source =3D "K:/test"
dest =3D "K:"
Dir.entries(source).reject { |d| %w{. ..}.include?(d) }.each do |file|
FileUtils.cp(File.join(source, file), unique_filename(dest))
end

--=20
Kendall Gifford
(e-mail address removed)
 
H

Hawksury Gear

Thanks very much , all worked very well. I can now,
- Copy all files from a directory with a new name to the required
destination.

I would appreciate if you can give some suggestions regarding the
following,

Problem: Defining a specific File Size when copying over, say of size=
2MB
For example if source file size is = 20MB, I want to get total of 10
files of size 2MB.

Something like,
# when copying if file.size > 2MB "Stop"
AND
# Create a new file
again when copying if file.size > 2MB "Stop"
# Create a new file
# And so on...

Probably,dividing the file size by 2 and then creating that many files
to copy the contents over
so if file.size = 20
total files = 20/2

Also the most difficult thing for me is how to keep track of what data
has been copied over already ?

Something like,
# Create a new file if size > 2MB
# AND Copy the data from the point onwards.

I hope that I have explained well what I actually want to achieve.

Any suggestions would be much appreciated including any methods in ruby
any common tricks for doing the above?

The Current Code i am using isn't intelligent it copies over an entire
file regardless of the file size,

Works perfectly fine,

def unique_filename(location, basename = '', extension = '.txt', digits
= 4)
# Initializing file extension
extension = extension ? ".#{extension}" : ''
index = 0
namer = lambda {
"#{basename}#{index.to_s.rjust(digits,'0')}#{extension}" }
name = namer.call
while File.exists?(File.join(location, name))
index = index + 1
name = namer.call
end
File.join(location, name)
end

Many Thanks,
Gear
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,039
Messages
2,570,376
Members
47,029
Latest member
EmiliaSton

Latest Threads

Top