Copying all Files with New Name

Discussion in 'Ruby' started by Hawksury Gear, Apr 5, 2010.

  1. 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,
    --
    Posted via http://www.ruby-forum.com/.
     
    Hawksury Gear, Apr 5, 2010
    #1
    1. Advertising

  2. >
    > 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
     
    Kendall Gifford, Apr 7, 2010
    #2
    1. Advertising

  3. Hawksury Gear, Apr 7, 2010
    #3
  4. 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
    --
    Posted via http://www.ruby-forum.com/.
     
    Hawksury Gear, Apr 8, 2010
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    497
  2. Shawn Mcclain
    Replies:
    0
    Views:
    185
    Shawn Mcclain
    Sep 28, 2007
  3. Os Ai
    Replies:
    6
    Views:
    101
    Os Ai
    May 15, 2009
  4. Replies:
    2
    Views:
    471
    Thomas 'PointedEars' Lahn
    Mar 11, 2008
  5. PhpCool
    Replies:
    9
    Views:
    248
    David Mark
    Oct 30, 2008
Loading...

Share This Page