/
tempfile.cr
94 lines (88 loc) · 2.12 KB
/
tempfile.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
require "c/stdlib"
# The `Tempfile` class is for managing temporary files.
# Every tempfile is operated as a `File`, including
# initializing, reading and writing.
#
# ```
# tempfile = Tempfile.new("foo")
# # or
# tempfile = Tempfile.open("foo") { |file|
# file.print("foobar")
# }
#
# File.size(tempfile.path) # => 6
# File.stat(tempfile.path).mtime # => 2015-10-20 13:11:12 UTC
# File.exists?(tempfile.path) # => true
# File.read_lines(tempfile.path) # => ["foobar"]
# ```
#
# Files created from this class are stored in a directory that handles
# temporary files.
#
# ```
# Tempfile.new("foo").path # => "/tmp/foo.ulBCPS"
# ```
#
# Also, it is encouraged to delete a tempfile after using it, which
# ensures they are not left behind in your filesystem until garbage collected.
#
# ```
# tempfile = Tempfile.new("foo")
# tempfile.unlink
# ```
class Tempfile < IO::FileDescriptor
# Creates a `Tempfile` with the given filename.
def initialize(name)
tmpdir = self.class.dirname + File::SEPARATOR
@path = "#{tmpdir}#{name}.XXXXXX"
fileno = LibC.mkstemp(@path)
if fileno == -1
raise Errno.new("mkstemp")
end
super(fileno, blocking: true)
end
# Retrieves the full path of a this tempfile.
#
# ```
# Tempfile.new("foo").path # => "/tmp/foo.ulBCPS"
# ```
getter path : String
# Creates a file with *filename*, and yields it to the given block.
# It is closed and returned at the end of this method call.
#
# ```
# tempfile = Tempfile.open("foo") { |file|
# file.print("bar")
# }
# File.read(tempfile.path) # => "bar"
# ```
def self.open(filename)
tempfile = Tempfile.new(filename)
begin
yield tempfile
ensure
tempfile.close
end
tempfile
end
# Returns the tmp dir used for tempfile.
#
# ```
# Tempfile.dirname # => "/tmp"
# ```
def self.dirname : String
unless tmpdir = ENV["TMPDIR"]?
tmpdir = "/tmp"
end
tmpdir = tmpdir + File::SEPARATOR unless tmpdir.ends_with? File::SEPARATOR
File.dirname(tmpdir)
end
# Deletes this tempfile.
def delete
File.delete(@path)
end
# ditto
def unlink
delete
end
end