Module: FileUtil

Includes:
Zlib
Defined in:
lib/ec2/amitools/fileutil.rb

Overview

Module containing file utility methods.

Constant Summary collapse

BUFFER_SIZE =

Buffer size in bytes.

1024 * 1024
PART_SUFFIX =
'.part.'

Class Method Summary collapse

Class Method Details

.assert_exists(filename) ⇒ Object

Assert the specified file exists. An exception is raised if it does not.



34
35
36
# File 'lib/ec2/amitools/fileutil.rb', line 34

def FileUtil.assert_exists(filename)
  raise FileError(filename, 'a required file could not be found') unless exists?(filename)
end

.cat(filenames, out_filename) ⇒ Object

Concatenate the specified files into a single file. If the specified output file already exists it will be overwritten. ((|filenames|)) An ordered collection of the names of split files. ((|out_filename|)) The output filename.



136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ec2/amitools/fileutil.rb', line 136

def FileUtil.cat(filenames, out_filename)
  File.open(out_filename, 'w') do |of|
    filenames.each do |filename|
      File.open(filename) do |file|
        while not (file.eof?)
          of.write(file.read(BUFFER_SIZE))
          of.flush
        end
      end
    end
  end
end

.compress(filename) ⇒ Object

Compress the specified file and return the path to the temporary compressed file that will be deleted upon termination of the process.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ec2/amitools/fileutil.rb', line 44

def FileUtil.compress(filename)
  outfilename = filename+'.gz'    
  GzipWriter.open(outfilename) do |outfile|
    begin
      File.open(filename, 'r') do |infile|
        while not (infile.eof)
           outfile.write(infile.read(BUFFER_SIZE))
        end
      end
    ensure

    end
  end
  outfilename
end

.directory?(fullname) ⇒ Boolean

—————————————————————————-#

Returns:

  • (Boolean)


157
158
159
# File 'lib/ec2/amitools/fileutil.rb', line 157

def FileUtil.directory?(fullname)
  File::Stat.new(fullname).directory?
end

.exists?(fullname) ⇒ Boolean

—————————————————————————-#

Returns:

  • (Boolean)


151
152
153
# File 'lib/ec2/amitools/fileutil.rb', line 151

def FileUtil.exists?(fullname)
  FileTest.exists?(fullname)
end

.expand(src_filename, dst_filename) ⇒ Object

Expand ((|src_filename|)) to ((|dst_filename|)).



65
66
67
68
69
70
71
72
73
# File 'lib/ec2/amitools/fileutil.rb', line 65

def FileUtil.expand(src_filename, dst_filename)
  GzipReader.open(src_filename) do |gzfile|
    File.open(dst_filename, 'w') do |file|
      while not (gzfile.eof?)
        file.write(gzfile.read(BUFFER_SIZE))
      end
    end
  end
end

.size(f) ⇒ Object

—————————————————————————-#



188
189
190
191
192
193
194
195
196
197
# File 'lib/ec2/amitools/fileutil.rb', line 188

def FileUtil.size(f)
  total =  `du -s #{f}`.split[0].to_i rescue nil
  if total.nil? or $?.exitstatus != 0
    total = 0
    Find.find(f) do |s| 
      total += File.directory?(s) ? 0 : File.size(s)
    end
  end
  total
end

.split(filename, part_name_prefix, cb_size, dst_dir) ⇒ Object

Split the specified file into chunks of the specified size. yields the <file,chunk,chunk size> to a block which writes the actual chunks The chunks are output to the local directory. Typical invocation looks like: FileUtil.split(‘file’,5){|sf,cf,cs| ChunkWriter.write_chunk(sf,cf,cs)}

((|filename|)) The file to split. ((|part_name_prefix|)) The prefix for the parts filenames. ((|cb_size|)) The chunk size in bytes. ((|dst_dir|)) The destination to create the file parts in.

Returns a list of the created filenames.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ec2/amitools/fileutil.rb', line 91

def FileUtil.split(filename, part_name_prefix, cb_size, dst_dir)
  begin
    # Check file exists and is accessible.
    begin
      file = File.new(filename, File::RDONLY)
    rescue SystemCallError => e
      raise FileError.new(filename, "could not open file to split", e)
    end
    
    # Create the part file upfront to catch any creation/access errors
    # before writing out data.
    nr_parts = (Float(File.size(filename)) / Float(cb_size)).ceil
    part_names = []
    nr_parts.times do |i|
      begin
        nr_parts_digits = nr_parts.to_s.length
        part_name_suffix = PART_SUFFIX + i.to_s.rjust(nr_parts_digits).gsub(' ', '0')
        part_names[i] = part_name = part_name_prefix + part_name_suffix
        FileUtils.touch File.join(dst_dir, part_name)
      rescue SystemCallError => e
        raise FileError.new(filename, "could not create part file", e)
      end
    end
    
    # Write parts to files.
    part_names.each do |part_file_name|
      File.open(File.join(dst_dir, part_file_name), 'w+') do |pf|
        write_chunk(file, pf, cb_size)
      end
    end

    part_names
  ensure
    file.close if not file.nil?
  end
end

.symlink?(fullname) ⇒ Boolean

—————————————————————————-#

Returns:

  • (Boolean)


163
164
165
# File 'lib/ec2/amitools/fileutil.rb', line 163

def FileUtil.symlink?(fullname)
  File::Stat.new(fullname).symlink?
end

.tempdir(basename, tmpdir = Dir::tmpdir, tries = 10) ⇒ Object

—————————————————————————-#



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/ec2/amitools/fileutil.rb', line 169

def FileUtil.tempdir(basename, tmpdir=Dir::tmpdir, tries=10)
  tmpdir = '/tmp' if $SAFE > 0 and tmpdir.tainted?
  fail = 0
  tmpname = nil
  begin
    begin
      tmpname = File.join(tmpdir, sprintf('%s%d.%s', basename, $$, Time.now.to_f.to_s))
    end until !File.exist? tmpname
  rescue
    fail += 1
    retry if fail < tries
    raise "failed to generate a temporary directory name '%s'" % tmpname
  end
  tmpname
end

.write_chunk(sf, cf, cs) ⇒ Object

Write chunk to file. ((|sf|)) Source file. ((|cf|)) Chunk file. ((|cs|)) Chunk size in bytes. Returns true if eof was encountered.



208
209
210
211
212
213
214
215
216
217
218
# File 'lib/ec2/amitools/fileutil.rb', line 208

def FileUtil.write_chunk(sf, cf, cs)
  cb_written = 0  # Bytes written.
  cb_left = cs    # Bytes left to write in this chunk.
  while (!sf.eof? && cb_left > 0) do
    buf = sf.read(BUFFER_SIZE < cb_left ? BUFFER_SIZE : cb_left)
    cf.write(buf)
    cb_written += buf.length
    cb_left = cs - cb_written
  end
  sf.eof
end