Class: File

Inherits:
Object
  • Object
show all
Extended by:
Windows::File::Constants, Windows::File::Functions, Windows::File::Structs
Includes:
Windows::File::Constants, Windows::File::Functions
Defined in:
lib/win32/file/attributes.rb

Constant Summary collapse

WIN32_FILE_ATTRIBUTE_VERSION =

The version of the win32-file library

'1.0.3'
ARCHIVE =

The file or directory is an archive. Typically used to mark files for backup or removal.

FILE_ATTRIBUTE_ARCHIVE
COMPRESSED =

The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is # the default for newly created files and subdirectories.

FILE_ATTRIBUTE_COMPRESSED
HIDDEN =

The file is hidden. Not included in an ordinary directory listing.

FILE_ATTRIBUTE_HIDDEN
NORMAL =

A file that does not have any other attributes set.

FILE_ATTRIBUTE_NORMAL
OFFLINE =

The data of a file is not immediately available. This attribute indicates that file data is physically moved to offline storage.

FILE_ATTRIBUTE_OFFLINE
READONLY =

The file is read only. Apps can read it, but not write to it or delete it.

FILE_ATTRIBUTE_READONLY
SYSTEM =

The file is part of or used exclusively by an operating system.

FILE_ATTRIBUTE_SYSTEM
TEMPORARY =

The file is being used for temporary storage.

FILE_ATTRIBUTE_TEMPORARY
INDEXED =

The file or directory is to be indexed by the content indexing service. Note that we have inverted the traditional definition.

0x0002000
CONTENT_INDEXED =

Synonym for File::INDEXED.

INDEXED

Constants included from Windows::File::Constants

Windows::File::Constants::COMPRESSION_FORMAT_DEFAULT, Windows::File::Constants::COMPRESSION_FORMAT_NONE, Windows::File::Constants::FILE_ATTRIBUTE_ARCHIVE, Windows::File::Constants::FILE_ATTRIBUTE_COMPRESSED, Windows::File::Constants::FILE_ATTRIBUTE_DIRECTORY, Windows::File::Constants::FILE_ATTRIBUTE_ENCRYPTED, Windows::File::Constants::FILE_ATTRIBUTE_HIDDEN, Windows::File::Constants::FILE_ATTRIBUTE_NORMAL, Windows::File::Constants::FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, Windows::File::Constants::FILE_ATTRIBUTE_OFFLINE, Windows::File::Constants::FILE_ATTRIBUTE_READONLY, Windows::File::Constants::FILE_ATTRIBUTE_REPARSE_POINT, Windows::File::Constants::FILE_ATTRIBUTE_SPARSE_FILE, Windows::File::Constants::FILE_ATTRIBUTE_SYSTEM, Windows::File::Constants::FILE_ATTRIBUTE_TEMPORARY, Windows::File::Constants::FILE_READ_DATA, Windows::File::Constants::FILE_SHARE_READ, Windows::File::Constants::FILE_SHARE_WRITE, Windows::File::Constants::FILE_WRITE_DATA, Windows::File::Constants::INVALID_FILE_ATTRIBUTES, Windows::File::Constants::INVALID_HANDLE_VALUE, Windows::File::Constants::OPEN_EXISTING

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.archive?(file) ⇒ Boolean

Returns whether or not the file or directory is an archive file or directory. Applications typically use this attribute to mark files for backup or removal.

Returns:

  • (Boolean)


145
146
147
# File 'lib/win32/file/attributes.rb', line 145

def self.archive?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_ARCHIVE)
end

.attributes(file) ⇒ Object

Returns an array of strings indicating the attributes for that file. The possible values are:

archive compressed directory encrypted hidden indexed normal offline readonly reparse_point sparse system temporary



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/win32/file/attributes.rb', line 71

def self.attributes(file)
  attributes = GetFileAttributesW(string_check(file).wincode)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  arr = []

  arr << 'archive' if attributes & FILE_ATTRIBUTE_ARCHIVE > 0
  arr << 'compressed' if attributes & FILE_ATTRIBUTE_COMPRESSED > 0
  arr << 'directory' if attributes & FILE_ATTRIBUTE_DIRECTORY > 0
  arr << 'encrypted' if attributes & FILE_ATTRIBUTE_ENCRYPTED > 0
  arr << 'hidden' if attributes & FILE_ATTRIBUTE_HIDDEN > 0
  arr << 'indexed' if attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED == 0
  arr << 'normal' if attributes & FILE_ATTRIBUTE_NORMAL > 0
  arr << 'offline' if attributes & FILE_ATTRIBUTE_OFFLINE > 0
  arr << 'readonly' if attributes & FILE_ATTRIBUTE_READONLY > 0
  arr << 'reparse_point' if attributes & FILE_ATTRIBUTE_REPARSE_POINT > 0
  arr << 'sparse' if attributes & FILE_ATTRIBUTE_SPARSE_FILE > 0
  arr << 'system' if attributes & FILE_ATTRIBUTE_SYSTEM > 0
  arr << 'temporary' if attributes & FILE_ATTRIBUTE_TEMPORARY > 0

  arr
end

.compressed?(file) ⇒ Boolean

Returns whether or not the file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.

Returns:

  • (Boolean)


154
155
156
# File 'lib/win32/file/attributes.rb', line 154

def self.compressed?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_COMPRESSED)
end

.encrypted?(file) ⇒ Boolean

Returns whether or not the file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.

Returns:

  • (Boolean)


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

def self.encrypted?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_ENCRYPTED)
end

.hidden?(file) ⇒ Boolean

Returns whether or not the file or directory is hidden. A hidden file does not show up in an ordinary directory listing.

Returns:

  • (Boolean)


170
171
172
# File 'lib/win32/file/attributes.rb', line 170

def self.hidden?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_HIDDEN)
end

.indexed?(file) ⇒ Boolean Also known as: content_indexed?

Returns whether or not the file or directory has been indexed by the content indexing service.

Returns:

  • (Boolean)


177
178
179
# File 'lib/win32/file/attributes.rb', line 177

def self.indexed?(file)
  !check_for_attribute(file, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
end

.normal?(file) ⇒ Boolean

Returns whether or not the file is a normal file or directory. A normal file or directory does not have any other attributes set.

Returns:

  • (Boolean)


184
185
186
# File 'lib/win32/file/attributes.rb', line 184

def self.normal?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_NORMAL)
end

.offline?(file) ⇒ Boolean

Returns whether or not the data of a file is available immediately. If true it indicates that the file data is physically moved to offline storage.

Returns:

  • (Boolean)


192
193
194
# File 'lib/win32/file/attributes.rb', line 192

def self.offline?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_OFFLINE)
end

.readonly?(file) ⇒ Boolean Also known as: read_only?

Returns whether or not the file is read-only. If a file is read-only then applications can read the file, but cannot write to it or delete it.

Note that this attribute is not honored on directories.

Returns:

  • (Boolean)


201
202
203
# File 'lib/win32/file/attributes.rb', line 201

def self.readonly?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_READONLY)
end

.remove_attributes(file, flags) ⇒ Object Also known as: unset_attr

Removes the file attributes based on the given (numeric) flags.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/win32/file/attributes.rb', line 124

def self.remove_attributes(file, flags)
  wfile = string_check(file).wincode
  attributes = GetFileAttributesW(wfile)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  attributes &= ~flags

  unless SetFileAttributesW(wfile, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

.reparse_point?(file) ⇒ Boolean

Returns true if the file or directory has an associated reparse point. A reparse point is a collection of user defined data associated with a file or directory. For more on reparse points, search msdn.microsoft.com.

Returns:

  • (Boolean)


210
211
212
# File 'lib/win32/file/attributes.rb', line 210

def self.reparse_point?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_REPARSE_POINT)
end

.set_attributes(file, flags) ⇒ Object Also known as: set_attr

Sets the file attributes based on the given (numeric) flags. This does not remove existing attributes, it merely adds to them. Use the File.remove_attributes method if you want to remove them.

Please not that certain attributes cannot always be applied. For example, you cannot convert a regular file into a directory. Common sense should guide you here.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/win32/file/attributes.rb', line 105

def self.set_attributes(file, flags)
  wfile = string_check(file).wincode
  attributes = GetFileAttributesW(wfile)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  attributes |= flags

  unless SetFileAttributesW(wfile, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

.sparse?(file) ⇒ Boolean

Returns whether or not the file is a sparse file. A sparse file is a file in which much of the data is zeros, typically image files.

Returns:

  • (Boolean)


217
218
219
# File 'lib/win32/file/attributes.rb', line 217

def self.sparse?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_SPARSE_FILE)
end

.system?(file) ⇒ Boolean

Returns whether or not the file or directory is a system file. A system file is a file that is part of the operating system or is used exclusively by the operating system.

Returns:

  • (Boolean)


225
226
227
# File 'lib/win32/file/attributes.rb', line 225

def self.system?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_SYSTEM)
end

.temporary?(file) ⇒ Boolean

Returns whether or not the file is being used for temporary storage.

File systems avoid writing data back to mass storage if sufficient cache memory is available, because often the application deletes the temporary file shortly after the handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data will be written after the handle is closed.

Returns:

  • (Boolean)


237
238
239
# File 'lib/win32/file/attributes.rb', line 237

def self.temporary?(file)
  check_for_attribute(file, FILE_ATTRIBUTE_TEMPORARY)
end

Instance Method Details

#archive=(bool) ⇒ Object

Sets whether or not the file is an archive file. Applications typically use this attribute to mark files for backup or removal.



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/win32/file/attributes.rb', line 253

def archive=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes |= FILE_ATTRIBUTE_ARCHIVE;
  else
    attributes &= ~FILE_ATTRIBUTE_ARCHIVE;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#compressed=(bool) ⇒ Object

Sets whether or not the file is a compressed file. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/win32/file/attributes.rb', line 278

def compressed=(bool)
  # We can't use get_osfhandle here because we need specific attributes
  handle = CreateFileW(
    self.path.wincode,
    FILE_READ_DATA | FILE_WRITE_DATA,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    nil,
    OPEN_EXISTING,
    0,
    0
  )

  if handle == INVALID_HANDLE_VALUE
    raise SystemCallError.new("CreateFile", FFI.errno)
  end

  in_buf = FFI::MemoryPointer.new(:ulong)
  bytes  = FFI::MemoryPointer.new(:ulong)

  compression_value = bool ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE
  in_buf.write_ulong(compression_value)

  begin
    bool = DeviceIoControl(
      handle,
      FSCTL_SET_COMPRESSION(),
      in_buf,
      in_buf.size,
      nil,
      0,
      bytes,
      nil
    )

    unless bool
      raise SystemCallError.new("DeviceIoControl", FFI.errno)
    end
  ensure
    CloseHandle(handle)
    in_buf.free
    bytes.free
  end

  self
end

#hidden=(bool) ⇒ Object

Sets the hidden attribute to true or false. Setting this attribute to true means that the file is not included in an ordinary directory listing.



327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/win32/file/attributes.rb', line 327

def hidden=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes |= FILE_ATTRIBUTE_HIDDEN;
  else
    attributes &= ~FILE_ATTRIBUTE_HIDDEN;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#indexed=(bool) ⇒ Object Also known as: content_indexed=

Sets the ‘indexed’ attribute to true or false. Setting this to false means that the file will not be indexed by the content indexing service.



352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/win32/file/attributes.rb', line 352

def indexed=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
  else
    attributes |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#normal=(bool) ⇒ Object

Sets the normal attribute. Note that only ‘true’ is a valid argument, which has the effect of removing most other attributes. Attempting to pass any value except true will raise an ArgumentError.



379
380
381
382
383
384
385
386
387
388
389
# File 'lib/win32/file/attributes.rb', line 379

def normal=(bool)
  unless bool
    raise ArgumentError, "only 'true' may be passed as an argument"
  end

  unless SetFileAttributesW(self.path.wincode, FILE_ATTRIBUTE_NORMAL)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#offline=(bool) ⇒ Object

Applications should not arbitrarily change this attribute.



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/win32/file/attributes.rb', line 399

def offline=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes |= FILE_ATTRIBUTE_OFFLINE;
  else
    attributes &= ~FILE_ATTRIBUTE_OFFLINE;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#readonly=(bool) ⇒ Object

Sets the readonly attribute. If set to true the the file or directory is readonly. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
# File 'lib/win32/file/attributes.rb', line 424

def readonly=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes |= FILE_ATTRIBUTE_READONLY;
  else
    attributes &= ~FILE_ATTRIBUTE_READONLY;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#sparse=(bool) ⇒ Object

Sets the file to a sparse (usually image) file. Note that you cannot remove the sparse property from a file.



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'lib/win32/file/attributes.rb', line 448

def sparse=(bool)
  unless bool
    warn 'cannot remove sparse property from a file - operation ignored'
    return
  end

  handle = CreateFileW(
    self.path.wincode,
    FILE_READ_DATA | FILE_WRITE_DATA,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    0,
    OPEN_EXISTING,
    FSCTL_SET_SPARSE(),
    0
  )

  if handle == INVALID_HANDLE_VALUE
    raise SystemCallError.new("CreateFile", FFI.errno)
  end

  bytes = FFI::MemoryPointer.new(:ulong)

  begin
    bool = DeviceIoControl(
      handle,
      FSCTL_SET_SPARSE(),
      nil,
      0,
      nil,
      0,
      bytes,
      nil
    )

    unless bool == 0
      raise SystemCallError.new("DeviceIoControl", FFI.errno)
    end
  ensure
    CloseHandle(handle)
    bytes.free
  end

  self
end

#system=(bool) ⇒ Object

that is part of the operating system or is used exclusively by it.



496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
# File 'lib/win32/file/attributes.rb', line 496

def system=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes |= FILE_ATTRIBUTE_SYSTEM;
  else
    attributes &= ~FILE_ATTRIBUTE_SYSTEM;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end

#temporary=(bool) ⇒ Object

Sets whether or not the file is being used for temporary storage.

File systems avoid writing data back to mass storage if sufficient cache memory is available, because often the application deletes the temporary file shortly after the handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data will be written after the handle is closed.



525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
# File 'lib/win32/file/attributes.rb', line 525

def temporary=(bool)
  wide_path  = self.path.wincode
  attributes = GetFileAttributesW(wide_path)

  if attributes == INVALID_FILE_ATTRIBUTES
    raise SystemCallError.new("GetFileAttributes", FFI.errno)
  end

  if bool
    attributes |= FILE_ATTRIBUTE_TEMPORARY;
  else
    attributes &= ~FILE_ATTRIBUTE_TEMPORARY;
  end

  unless SetFileAttributesW(wide_path, attributes)
    raise SystemCallError.new("SetFileAttributes", FFI.errno)
  end

  self
end