Class: MemFs::File

Inherits:
Object
  • Object
show all
Extended by:
FilesystemAccess, SingleForwardable
Includes:
Constants, Enumerable, 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

Constructor Details

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

Returns a new instance of File.



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/memfs/file.rb', line 229

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

#pathObject (readonly)

Returns the value of attribute path.



227
228
229
# File 'lib/memfs/file.rb', line 227

def path
  @path
end

Class Method Details

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



59
60
61
# File 'lib/memfs/file.rb', line 59

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

.atime(path) ⇒ Object



63
64
65
# File 'lib/memfs/file.rb', line 63

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

.chmod(mode_int, *paths) ⇒ Object



67
68
69
70
71
# File 'lib/memfs/file.rb', line 67

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

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



73
74
75
76
77
78
# File 'lib/memfs/file.rb', line 73

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

.ctime(path) ⇒ Object



80
81
82
# File 'lib/memfs/file.rb', line 80

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

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

Returns:

  • (Boolean)


84
85
86
# File 'lib/memfs/file.rb', line 84

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

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



89
90
91
# File 'lib/memfs/file.rb', line 89

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

.ftype(path) ⇒ Object



93
94
95
# File 'lib/memfs/file.rb', line 93

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

.identical?(path1, path2) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
102
103
# File 'lib/memfs/file.rb', line 99

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

.lchmod(mode_int, *file_names) ⇒ Object



105
106
107
108
109
# File 'lib/memfs/file.rb', line 105

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



111
112
113
# File 'lib/memfs/file.rb', line 111

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


115
116
117
118
# File 'lib/memfs/file.rb', line 115

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

.lstat(path) ⇒ Object



120
121
122
# File 'lib/memfs/file.rb', line 120

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

.mtime(path) ⇒ Object



124
125
126
# File 'lib/memfs/file.rb', line 124

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

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



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

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



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

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


155
156
157
# File 'lib/memfs/file.rb', line 155

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

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



159
160
161
# File 'lib/memfs/file.rb', line 159

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

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



163
164
165
# File 'lib/memfs/file.rb', line 163

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

.rename(old_name, new_name) ⇒ Object



167
168
169
170
# File 'lib/memfs/file.rb', line 167

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

.reset!Object



172
173
174
# File 'lib/memfs/file.rb', line 172

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

.size(path) ⇒ Object



176
177
178
# File 'lib/memfs/file.rb', line 176

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

.size?(path) ⇒ Boolean

Returns:

  • (Boolean)


180
181
182
183
# File 'lib/memfs/file.rb', line 180

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

.stat(path) ⇒ Object



185
186
187
# File 'lib/memfs/file.rb', line 185

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


189
190
191
192
# File 'lib/memfs/file.rb', line 189

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

.symlink?(path) ⇒ Boolean

Returns:

  • (Boolean)


194
195
196
# File 'lib/memfs/file.rb', line 194

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

.truncate(path, length) ⇒ Object



198
199
200
201
# File 'lib/memfs/file.rb', line 198

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

.umask(integer = nil) ⇒ Object



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

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

  @umask = integer if integer

  old_value
end


211
212
213
214
215
216
# File 'lib/memfs/file.rb', line 211

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

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



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

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



245
246
247
248
# File 'lib/memfs/file.rb', line 245

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

#chown(uid, gid = nil) ⇒ Object



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

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

#closeObject



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

def close
  self.closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


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

def closed?
  closed
end

#each(sep = $/, &block) ⇒ Object



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

def each(sep = $/, &block)
  return to_enum(__callee__) unless block_given?
  fail IOError, 'not opened for reading' unless readable?
  content.each_line(sep) { |line| block.call(line) }
  self
end

#lstatObject



270
271
272
# File 'lib/memfs/file.rb', line 270

def lstat
  File.lstat(path)
end

#posObject



274
275
276
# File 'lib/memfs/file.rb', line 274

def pos
  entry.pos
end

#puts(text) ⇒ Object

Raises:

  • (IOError)


278
279
280
281
282
# File 'lib/memfs/file.rb', line 278

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

  content.puts text
end

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



284
285
286
287
# File 'lib/memfs/file.rb', line 284

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

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



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

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



303
304
305
# File 'lib/memfs/file.rb', line 303

def size
  entry.size
end

#statObject



307
308
309
# File 'lib/memfs/file.rb', line 307

def stat
  File.stat(path)
end

#write(string) ⇒ Object

Raises:

  • (IOError)


311
312
313
314
315
# File 'lib/memfs/file.rb', line 311

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

  content.write(string.to_s)
end