Class: MemFs::File

Inherits:
Object
  • Object
show all
Extended by:
FilesystemAccess, SingleForwardable
Includes:
FilesystemAccess
Defined in:
lib/memfs/file.rb,
lib/memfs/file/stat.rb

Defined Under Namespace

Classes: Stat

Constant Summary collapse

MODE_MAP =
{
  'r'  => RDONLY,
  'r+' => RDWR,
  'w'  => CREAT|TRUNC|WRONLY,
  'w+' => CREAT|TRUNC|RDWR,
  'a'  => CREAT|APPEND|WRONLY,
  'a+' => CREAT|APPEND|RDWR
}
SUCCESS =
0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FilesystemAccess

fs

Constructor Details

#initialize(filename, mode = RDONLY, perm = nil, opt = nil) ⇒ File

Returns a new instance of File.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/memfs/file.rb', line 234

def initialize(filename, mode = RDONLY, perm = nil, opt = nil)
  unless opt.nil? || opt.is_a?(Hash)
    raise ArgumentError, "wrong number of arguments (4 for 1..3)"
  end

  @path = filename

  self.opening_mode = str_to_mode_int(mode)

  fs.touch(filename) if create_file?

  self.entry = fs.find(filename)

  entry.content.clear if truncate_file?
end

Instance Attribute Details

#closedObject

Returns the value of attribute closed.



229
230
231
# File 'lib/memfs/file.rb', line 229

def closed
  @closed
end

#entryObject

Returns the value of attribute entry.



229
230
231
# File 'lib/memfs/file.rb', line 229

def entry
  @entry
end

#opening_modeObject

Returns the value of attribute opening_mode.



229
230
231
# File 'lib/memfs/file.rb', line 229

def opening_mode
  @opening_mode
end

#pathObject (readonly)

Returns the value of attribute path.



232
233
234
# File 'lib/memfs/file.rb', line 232

def path
  @path
end

Class Method Details

.absolute_path(path, dir_string = fs.pwd) ⇒ Object



61
62
63
# File 'lib/memfs/file.rb', line 61

def self.absolute_path(path, dir_string = fs.pwd)
  original_file_class.absolute_path(path, dir_string)
end

.atime(path) ⇒ Object



65
66
67
# File 'lib/memfs/file.rb', line 65

def self.atime(path)
  stat(path).atime
end

.chmod(mode_int, *paths) ⇒ Object



69
70
71
72
73
# File 'lib/memfs/file.rb', line 69

def self.chmod(mode_int, *paths)
  paths.each do |path|
    fs.chmod mode_int, path
  end
end

.chown(uid, gid, *paths) ⇒ Object



75
76
77
78
79
80
# File 'lib/memfs/file.rb', line 75

def self.chown(uid, gid, *paths)
  paths.each do |path|
    fs.chown(uid, gid, path)
  end
  paths.size
end

.ctime(path) ⇒ Object



82
83
84
# File 'lib/memfs/file.rb', line 82

def self.ctime(path)
  stat(path).ctime
end

.exists?(path) ⇒ Boolean Also known as: exist?

Returns:

  • (Boolean)


86
87
88
# File 'lib/memfs/file.rb', line 86

def self.exists?(path)
  !!fs.find(path)
end

.expand_path(file_name, dir_string = fs.pwd) ⇒ Object



91
92
93
# File 'lib/memfs/file.rb', line 91

def self.expand_path(file_name, dir_string = fs.pwd)
  original_file_class.expand_path(file_name, dir_string)
end

.ftype(path) ⇒ Object



95
96
97
# File 'lib/memfs/file.rb', line 95

def self.ftype(path)
  fs.find!(path) && lstat(path).ftype
end

.identical?(path1, path2) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
104
105
# File 'lib/memfs/file.rb', line 101

def self.identical?(path1, path2)
  fs.find!(path1).dereferenced === fs.find!(path2).dereferenced
rescue Errno::ENOENT
  false
end

.lchmod(mode_int, *file_names) ⇒ Object



107
108
109
110
111
# File 'lib/memfs/file.rb', line 107

def self.lchmod(mode_int, *file_names)
  file_names.each do |file_name|
    fs.chmod mode_int, file_name
  end
end

.lchown(uid, gid, *paths) ⇒ Object



113
114
115
# File 'lib/memfs/file.rb', line 113

def self.lchown(uid, gid, *paths)
  chown uid, gid, *paths
end


117
118
119
120
# File 'lib/memfs/file.rb', line 117

def self.link(old_name, new_name)
  fs.link old_name, new_name
  SUCCESS
end

.lstat(path) ⇒ Object



122
123
124
# File 'lib/memfs/file.rb', line 122

def self.lstat(path)
  Stat.new(path)
end

.mtime(path) ⇒ Object



126
127
128
# File 'lib/memfs/file.rb', line 126

def self.mtime(path)
  stat(path).mtime
end

.open(filename, mode = RDONLY, *perm_and_opt) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/memfs/file.rb', line 130

def self.open(filename, mode = RDONLY, *perm_and_opt)
  file = self.new(filename, mode, *perm_and_opt)

  if block_given?
    yield file
  else
    file
  end
ensure
  file.close if file && block_given?
end

.read(path, *args) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/memfs/file.rb', line 142

def self.read(path, *args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  options = { mode: RDONLY, encoding: nil, open_args: nil }.merge(options)
  open_args = options[:open_args] ||
              [options[:mode], encoding: options[:encoding]]

  length, offset = args

  file = open(path, *open_args)
  file.seek(offset || 0)
  file.read(length)
ensure
  file.close if file
end


157
158
159
# File 'lib/memfs/file.rb', line 157

def self.readlink(path)
  fs.find!(path).target
end

.realdirpath(path, dir_string = fs.pwd) ⇒ Object



161
162
163
# File 'lib/memfs/file.rb', line 161

def self.realdirpath(path, dir_string = fs.pwd)
  loose_dereference_path(absolute_path(path, dir_string))
end

.realpath(path, dir_string = fs.pwd) ⇒ Object



165
166
167
# File 'lib/memfs/file.rb', line 165

def self.realpath(path, dir_string = fs.pwd)
  dereference_path(absolute_path(path, dir_string))
end

.rename(old_name, new_name) ⇒ Object



169
170
171
172
# File 'lib/memfs/file.rb', line 169

def self.rename(old_name, new_name)
  fs.rename(old_name, new_name)
  SUCCESS
end

.reset!Object



174
175
176
# File 'lib/memfs/file.rb', line 174

def self.reset!
  @umask = original_file_class.umask
end

.size(path) ⇒ Object



178
179
180
# File 'lib/memfs/file.rb', line 178

def self.size(path)
  fs.find!(path).size
end

.size?(path) ⇒ Boolean

Returns:

  • (Boolean)


182
183
184
185
# File 'lib/memfs/file.rb', line 182

def self.size?(path)
  file = fs.find(path)
  file && file.size > 0 && file.size
end

.stat(path) ⇒ Object



187
188
189
# File 'lib/memfs/file.rb', line 187

def self.stat(path)
  Stat.new(path, true)
end


191
192
193
194
# File 'lib/memfs/file.rb', line 191

def self.symlink(old_name, new_name)
  fs.symlink old_name, new_name
  SUCCESS
end

.symlink?(path) ⇒ Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/memfs/file.rb', line 196

def self.symlink?(path)
  lstat_query(path, :symlink?)
end

.truncate(path, length) ⇒ Object



200
201
202
203
# File 'lib/memfs/file.rb', line 200

def self.truncate(path, length)
  fs.find!(path).content.truncate(length)
  SUCCESS
end

.umask(integer = nil) ⇒ Object



205
206
207
208
209
210
211
# File 'lib/memfs/file.rb', line 205

def self.umask(integer = nil)
  old_value = @umask || original_file_class.umask

  @umask = integer if integer

  old_value
end


213
214
215
216
217
218
# File 'lib/memfs/file.rb', line 213

def self.unlink(*paths)
  paths.each do |path|
    fs.unlink(path)
  end
  paths.size
end

.utime(atime, mtime, *file_names) ⇒ Object



221
222
223
224
225
226
227
# File 'lib/memfs/file.rb', line 221

def self.utime(atime, mtime, *file_names)
  file_names.each do |file_name|
    fs.find!(file_name).atime = atime
    fs.find!(file_name).mtime = mtime
  end
  file_names.size
end

Instance Method Details

#chmod(mode_int) ⇒ Object



250
251
252
253
# File 'lib/memfs/file.rb', line 250

def chmod(mode_int)
  fs.chmod(mode_int, path)
  SUCCESS
end

#chown(uid, gid = nil) ⇒ Object



255
256
257
258
# File 'lib/memfs/file.rb', line 255

def chown(uid, gid = nil)
  fs.chown(uid, gid, path)
  SUCCESS
end

#closeObject



260
261
262
# File 'lib/memfs/file.rb', line 260

def close
  self.closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


264
265
266
# File 'lib/memfs/file.rb', line 264

def closed?
  closed
end

#contentObject



268
269
270
# File 'lib/memfs/file.rb', line 268

def content
  entry.content
end

#lstatObject



272
273
274
# File 'lib/memfs/file.rb', line 272

def lstat
  File.lstat(path)
end

#posObject



276
277
278
# File 'lib/memfs/file.rb', line 276

def pos
  entry.pos
end

#puts(text) ⇒ Object

Raises:

  • (IOError)


280
281
282
283
284
# File 'lib/memfs/file.rb', line 280

def puts(text)
  raise IOError, 'not opened for writing' unless writable?

  content.puts text
end

#read(length = nil, buffer = '') ⇒ Object



286
287
288
289
# File 'lib/memfs/file.rb', line 286

def read(length = nil, buffer = '')
  default = length ? nil : ''
  content.read(length, buffer) || default
end

#seek(amount, whence = IO::SEEK_SET) ⇒ Object



291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/memfs/file.rb', line 291

def seek(amount, whence = IO::SEEK_SET)
  new_pos = case whence
  when IO::SEEK_CUR then entry.pos + amount
  when IO::SEEK_END then content.to_s.length + amount
  when IO::SEEK_SET then amount
  end

  if new_pos.nil? || new_pos < 0
    raise Errno::EINVAL, path
  end

  entry.pos = new_pos and 0
end

#sizeObject



305
306
307
# File 'lib/memfs/file.rb', line 305

def size
  entry.size
end

#statObject



309
310
311
# File 'lib/memfs/file.rb', line 309

def stat
  File.stat(path)
end

#write(string) ⇒ Object

Raises:

  • (IOError)


313
314
315
316
317
# File 'lib/memfs/file.rb', line 313

def write(string)
  raise IOError, 'not opened for writing' unless writable?

  content.write(string.to_s)
end