Class: EM::File
- Inherits:
-
Object
- Object
- EM::File
- Defined in:
- lib/em-files.rb
Overview
Sequenced file reader and writer.
Constant Summary collapse
- RWSIZE =
Holds the default size of block operated during one tick.
65536
Instance Attribute Summary collapse
-
#mode ⇒ String
readonly
Holds mode of the object.
-
#native ⇒ IO
Holds file object.
-
#rw_len ⇒ Integer
Indicates block size for operate with in one tick.
Class Method Summary collapse
-
.open(filepath, mode = "r", rwsize = self::RWSIZE, &block) ⇒ File
Opens the file.
- .read(filepath, rwsize = self::RWSIZE, filter = nil, &block) ⇒ Object
-
.write(filepath, data = "", rwsize = self::RWSIZE, filter = nil, &block) ⇒ Object
Writes data to file and closes it.
Instance Method Summary collapse
-
#close ⇒ Object
Closes the file.
-
#initialize(filepath, mode = "r", rwsize = self.class::RWSIZE) ⇒ File
constructor
Constructor.
-
#read(length = nil, filter = nil, &block) ⇒ Object
Reads data from file.
-
#reopen! ⇒ Object
Reopens the file with the original mode.
-
#write(data, filter = nil, &block) ⇒ Object
Writes data to file.
Constructor Details
#initialize(filepath, mode = "r", rwsize = self.class::RWSIZE) ⇒ File
Constructor. If IO object is given instead of filepath, uses it as native one and mode
argument is ignored.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/em-files.rb', line 137 def initialize(filepath, mode = "r", rwsize = self.class::RWSIZE) @mode = mode @rw_len = rwsize rwsize = self::RWSIZE if rwsize.nil? # If filepath is directly IO, uses it if filepath.io? @native = filepath else @native = ::File::open(filepath, mode) end end |
Instance Attribute Details
#mode ⇒ String (readonly)
Holds mode of the object.
125 126 127 |
# File 'lib/em-files.rb', line 125 def mode @mode end |
#native ⇒ IO
Holds file object.
109 110 111 |
# File 'lib/em-files.rb', line 109 def native @native end |
#rw_len ⇒ Integer
Indicates block size for operate with in one tick.
117 118 119 |
# File 'lib/em-files.rb', line 117 def rw_len @rw_len end |
Class Method Details
.open(filepath, mode = "r", rwsize = self::RWSIZE, &block) ⇒ File
Opens the file.
In opposite to appropriate Ruby method, “block syntax” is only syntactic sugar, file isn’t closed after return from block because processing is asynchronous so it doesn’t know when is convenient to close the file.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/em-files.rb', line 44 def self.open(filepath, mode = "r", rwsize = self::RWSIZE, &block) # 64 kilobytes rwsize = self::RWSIZE if rwsize.nil? file = self::new(filepath, mode, rwsize) if not block.nil? block.call(file) end return file end |
.read(filepath, rwsize = self::RWSIZE, filter = nil, &block) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/em-files.rb', line 68 def self.read(filepath, rwsize = self::RWSIZE, filter = nil, &block) rwsize = self::RWSIZE if rwsize.nil? self::open(filepath, "rb", rwsize) do |io| io.read(nil, filter) do |out| io.close() block.call(out) end end end |
.write(filepath, data = "", rwsize = self::RWSIZE, filter = nil, &block) ⇒ Object
Writes data to file and closes it. Writes them in binary mode. If IO object is given instead of filepath, uses it as native one and mode
argument is ignored.
92 93 94 95 96 97 98 99 100 |
# File 'lib/em-files.rb', line 92 def self.write(filepath, data = "", rwsize = self::RWSIZE, filter = nil, &block) rwsize = self::RWSIZE if rwsize.nil? self::open(filepath, "wb", rwsize) do |io| io.write(data, filter) do |length| io.close() block.call(length) end end end |
Instance Method Details
#close ⇒ Object
Closes the file.
295 296 297 |
# File 'lib/em-files.rb', line 295 def close @native.close end |
#read(length, &block) ⇒ Object #read(&block) ⇒ Object
Reads data from file.
It will reopen the file if EBADF: Bad file descriptor of File
class IO object will occur.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/em-files.rb', line 170 def read(length = nil, filter = nil, &block) buffer = "" pos = 0 # Arguments if length.kind_of? Proc filter = length end worker = Proc::new do # Sets length for read if not length.nil? rlen = length - buffer.length if rlen > @rw_len rlen = @rw_len end else rlen = @rw_len end # Reads begin chunk = @native.read(rlen) if not filter.nil? chunk = filter.call(chunk) end buffer << chunk rescue Errno::EBADF if @native.kind_of? ::File self.reopen! @native.seek(pos) redo else raise end end pos = @native.pos # Returns or continues work if @native.eof? or (buffer.length == length) if not block.nil? block.call(buffer) # returns result end else EM::next_tick { worker.call() } # continues work end end worker.call() end |
#reopen! ⇒ Object
Reopens the file with the original mode.
229 230 231 |
# File 'lib/em-files.rb', line 229 def reopen! @native = ::File.open(@native.path, @mode) end |
#write(data, filter = nil, &block) ⇒ Object
Writes data to file. Supports writing both strings or copying from another IO object.
It will reopen the file if EBADF: Bad file descriptor of File
class IO object will occur on File
object.
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/em-files.rb', line 247 def write(data, filter = nil, &block) pos = 0 if data.io? io = data else io = StringIO::new(data) end worker = Proc::new do # Writes begin chunk = io.read(@rw_len) if not filter.nil? chunk = filter.call(chunk) end @native.write(chunk) rescue Errno::EBADF if @native.kind_of? File self.reopen! @native.seek(pos) redo else raise end end pos = @native.pos # Returns or continues work if io.eof? if not block.nil? block.call(pos) # returns result end else EM::next_tick { worker.call() } # continues work end end worker.call() end |