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 = "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
path = File.join testdir, file
if File.file? path
File\.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.
File\.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')
end
end
end
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 fine.
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 = '', extension = nil, digits = 4)
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 += 1
name = namer.call
end
File.join(location, name)
end
···
#
# Example Usage:
#
require 'fileutils'
source = "K:/test"
dest = "K:"
Dir.entries(source).reject { |d| %w{. ..}.include?(d) }.each do |file|
FileUtils.cp(File.join(source, file), unique_filename(dest))
end
--
Kendall Gifford
zettabyte@gmail.com