Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
api:buffer:zh [2023/10/16 08:40]
hfsr [静态方法]
api:buffer:zh [2023/11/29 05:36] (current)
hfsr [接口方法]
Line 1: Line 1:
 Buffer(缓冲) API Buffer(缓冲) API
 =========== ===========
-`buffer`库提供了便于使用的IO流。本库提供的流更像是`io`库提供的,由`io.open`返回的流,**不像**`filesystem.open`返回的原始流,后者支持的方法没有前者那么多。下文[[api:​buffer:​zh#​实例方法|实例方法]]板块列出的方法可用于从`io.open`函数获取的文件句柄因此就算你没打算构建自定义带缓冲IO流,此API文档也会大有裨益。+`buffer`库提供了便于使用的IO流。本库提供的流更像是`io`库提供的,由`io.open`返回的流,**不像**`filesystem.open`返回的原始流,后者支持的方法没有前者那么多。下文[[api:​buffer:​zh#​实例方法|实例方法]]板块列出的方法可用于从`io.open`函数获取的文件句柄因此就算你没打算构建自定义带缓冲流,此API文档也会大有裨益。
  
-此外,该API还允许你创建带缓冲IO流。你需要提供后端的流式读取和流式写入,buffer库提供数据缓冲与格式化。一般而言,用户无需构建自己的带缓冲输入输出流。以备参考,io库就使用了带缓冲IO流(包含文件io和控制台io)。+此外,该API还能让你创建带缓冲流。你需要提供后端的流式读取和流式写入,buffer库提供数据缓冲与格式化。一般而言,用户无需构建自己的带缓冲流。以备参考,io库就使用了带缓冲流(包含文件io和控制台io)。
  
 静态方法 静态方法
Line 11: Line 11:
 - `buffer.new([mode:​ string], stream: table)` - `buffer.new([mode:​ string], stream: table)`
  
-用读写模式(`mode`)来修饰传入的流(`stream`),以创建一个带缓冲IO流。模式(`mode`)可以为只读(r或`nil`)、读写(rw)或仅写入(w)。请查看`stream`对象所需流[[api:​buffer:​zh#​实例方法|实例方法]]有关内容。+  将传入的流(`stream`)封装上读写模式(`mode`),以创建一个带缓冲IO流。模式(`mode`)可以为只读(r或`nil`)、读写(rw)或仅写入(w)。请查看`stream`对象所需流[[api:​buffer:​zh#​实例方法|实例方法]]有关内容。
  
-Instance Methods+实例方法
 ----------- -----------
-The following methods can only be called on instances created by `buffer.new` ​(**note** file handles returned by `io.open` ​are  also buffered streams, created with `buffer.new`). These methods are instance methods, requiring instance call notation ​`:`. In order to help differentiate these instance methods from static methods (e.g. `buffer.new`), `b:` will be used to prefix the method names. +下列方法只能在`buffer.new`创建的实例上调用(**注意:**`io.open`返回的文件句柄也是`buffer.new`创建的带缓冲流)。这些方法均为实例方法,需要实例调用符号`:`。为了有助于区分这些实例方法与静态方法(例如`buffer.new`),这些方法名将会加上`b:`作为前缀。
- +
-- `b:​flush()` +
- +
-  If any data is buffered it is immediately written to the stream and released. +
-- `b:​close()` +
- +
-  Flushes the buffer and closes the wrapped stream. +
-- `b:​setvbuf([mode:​ string], [size: number]) mode, size` +
- +
-  Sets the buffering `mode` and `size` and returns the result `mode` and `size`. The amount of data buffered is specified by `size` which defaults to [512, 8192] bytes, depending on available system memory. `mode` and `size` can be nil, in which case the previous values are used for either. `size` is also used in `read(n)` calls to the stream. +
-   +
-  Modes only affect `write`, which include: +
-  * "​no"​ writes are immediately pushed to the stream. +
-  * "​full"​ writes are buffered up to `size` bytes. This is the default mode. +
-  * "​line"​ writes are buffered until newlines are found or `size` is reached, whichever comes first. +
- +
-- `b:​write([values...])` +
- +
-  Writes each `value` to the stream, first buffering based on the mode and buffer size (see `setvbuf`). Note that to write to a file, you have to open it for *write*.+
  
 +- `b:​flush()`  ​
 +  如果缓冲区存在任何数据,立即将其写入到IO流并释放。  ​
 +\\
 +- `b:​close()`  ​
 +  清空缓冲区并关闭封装的流。  ​
 +\\
 +- `b:​setvbuf([mode:​ string], [size: number]) mode, size`  ​
 +  设定缓冲区的模式(`mode`)和大小(`size`),并返回修改后的模式(`mode`)和大小(`size`)。`size`指定了缓冲的数据量,默认范围为[512,​ 8192]字节,根据可用系统内存而变化。`mode`和`size`可以为nil,此时将会沿用先前的值。`size`还被用于对流的`read(n)`调用。  ​
 +  模式只影响`write`方法,可用值包括: ​
 +  * `no`:写入数据被立即推送进IO流。
 +  * `full`:写入数据会被缓存,直到尺寸到达`size`字节。这是默认模式。
 +  * `line`:写入数据会被缓存,直到出现换行或达到`size`上限。\\
 +  \\
 +- `b:​write([values...])`  ​
 +  将所有的`value`写入到IO流,首先会依据缓冲模式和缓冲区大小(参见`setvbuf`)进行缓存。请注意要写入文件的话,需要将文件以**可写入**模式打开。\\
  
 ```lua ```lua
Line 41: Line 37:
 file:​write("​abc",​ "​def",​ "​\n"​) file:​write("​abc",​ "​def",​ "​\n"​)
 file:​close() file:​close()
--- foo.txt ​now has "​abcdef\n"​+-- foo.txt中现在的内容为"​abcdef\n"​
 ``` ```
  
- +- `b:​lines([line_formats...]) string array` ​  
-- `b:​lines([line_formats...]) string array` +  ​返回一个迭代器,其会从IO流进行读取,直到读取到`nil`。每次读取时,都会将参数列表`line_formmats`传递给`stream:​read(...)`。绝大多数使用情况下都不需要定义`line_format`,也就是不给`line()`传参。迭代器的默认行为(即没有`line_format`时)是每次从流中读取一行内容。
- +
-  ​Returns a function iterator which reads from the stream until it reaches ​nil. On each read, the `line_formatslist of args as passed to `stream:​read(...)`. The overwhelmingly typical use is to not define ​`line_formats`, i.e. passing no args to `lines()`. The default behavior (i..e without ​`line_formats`) is to read a "​line"​ at a time from the stream.+
  
 ```lua ```lua
Line 57: Line 51:
 ``` ```
  
-- `b:​read([formats...]) string...` +- `b:​read([formats...]) string...` ​  
- +  ​比较高级的读取器,可支持多种格式。首先,如果不指定`format`调用,即参数列表留空,它会从流中读取下一行,等价于`read("​*l"​)`。   
-  ​A fairly advanced reader that support various formats. First of all, if called with no `format`, i.e an empty param list, it reads the next line from the stream, which is equivalent to `read("​*l"​)` +每个`format`值都会先从IO流中读出,再一次性以多个返回值的形式返回。请注意格式字符串都有 ​\* 前缀,而且只有字符串的第一个字符有意义,其余字符将会被忽略。  ​ 
-   +  ​下列是支持的格式:  ​ 
-  ​Each ​`format` ​is read from the stream and all returned in a multiple return value list of the results. Note all format strings are prefixed with \* and also note that only the first char of the string names of the formats matters, the rest is ignored. These are the supported formats: +  一个数字值,例如`10`   
- +  ​从IO流读取**n**个字节(以二进制模式)或字符(以文本模式),结果将以字符串形式返回。参见[[api:​non-standard-lua-libs#​input_and_output_facilities|io.open]]以获取有关如何以不同模式打开文件的更多信息。  ​ 
-    a number value, e.g. `10` +  ​示例:`local chars = b:​read(10)` ​  
- +\\ 
-    Read **n** bytes (in binary mode) or chars (in text mode) from the stream; result is returned as a string. See [[api:​non-standard-lua-libs#​input_and_output_facilities|io.open]] ​for more details about how to open files in different modes. +  `*n`或者`*number`  ​ 
- +  ​从IO流中读取下一组可被解释为数字的字节。请注意读取到的数字会受到打开模式为二进制还是文本的影响。参见[[api:​non-standard-lua-libs#​input_and_output_facilities|io.open]]以获取有关如何以不同模式打开文件的更多信息。  ​ 
-    ​`local chars = b:​read(10)` +  ​示例:`local number = b:​read("​*n"​)` ​  
- +\\ 
-    "\*n" or "\*number" +  `*l`或者`*line`  ​ 
- +  ​从IO流中读取下一行,截掉换行标记(可能是 ​\n,\r\r\n)。  ​ 
-    Read the next series of bytes from the stream that can be interpreted as a number. Note that reading numbers is also affected by the open mode, binary or text. See [[api:​non-standard-lua-libs#​input_and_output_facilities|io.open]] ​for more details about how to open files in different modes.. +  ​示例:`local line = b:​read("​*l"​)` ​  
- +\\ 
-    ​`local number = b:​read("​*n"​)` +  `*L`或者`*Line`  ​ 
- +  ​从IO流中读取下一行,类似`*line`,但是在结果中保留换行标记。  ​ 
-    "\*l" or "\*line" +  ​示例:`local whole_line = b:​read("​*L"​)` ​  
- +\\ 
-    Read the next line from the stream, chopping off the line ending marker (which may be \n, \r, or \r\n) +  `*a`或者`*all`  ​ 
- +  ​从IO流中读取所有剩余内容,直到遇到nil。在此读取格式后再指定其他格式没有意义。  ​ 
-    ​`local line = b:​read("​*l"​)` +  ​示例:`local the_whole_file = b:​read("​*a"​)`\\ 
- +  \\ 
-    "\*L" or "\*Line" +- `b:​getTimeout() number` ​  
- +  ​返回当前带缓冲流设定的超时时间(单位为秒)。默认超时时间为`math.huge`。参阅`setTimeout`以获取有关于带缓冲流超时时间影响的更多信息。 ​  
-    Read the next line from the stream, like "*line", but preserves the line ending marker as part of the result +\\
- +
-    ​`local whole_line = b:​read("​*L"​)` +
- +
-    "\*a" or "\*all" +
- +
-    Reads all remaining data from the stream until nil. There would be no point in having formats following this. +
- +
-    ​`local the_whole_file = b:​read("​*a"​)` +
- +
-- `b:​getTimeout() number` +
- +
-  ​Returns the current timeout (in seconds) set on the buffered stream. ​`math.huge` ​is the default timeout. Read `setTimeout` ​for more information about the effects of a buffered stream timeout.+
 - `b:​setTimeout(timeout)` - `b:​setTimeout(timeout)`
- +  设定带缓冲流限制`read`操作的时长,单位为秒。请注意此超时值无法被严格遵守。只需一次`readChunk`(实际调用`read`方法的内部方法)即可完成的读取操作中不会检查`timeout`的限制。只有在流读取操作的间隔才会检查是否超时(下附一份样例)。因此,如果一次读取操作中需要多次块读取,并且首次块读取开始和最后一次块读取开始之间的时长大于等于超时时间,IO流会出错。再次强调,超时时间默认为`math.huge`
-  Sets the time in seconds a buffered stream will try to limit a `read` ​operation. Note that this timeout cannot be strictly adhered to. A read operation that completes within a single ​`readChunk` ​(an internal method that invokes the actual ​`read` ​on the stream) does not check the `timeout` ​limit. Timeout is only checked between stream reads within a single buffered read (an example follows). Thus, if a read requires multiple chunk reads, and the time between the start of the first read before the start of the last read is greater than or equal to the timeout, then the buffered stream will error. Again note that a timeout is default ​`math.huge`.+
  
  
 ```lua ```lua
 local file = buffer.new("​r",​ { read = function() os.sleep(5) return "​a"​ end }) local file = buffer.new("​r",​ { read = function() os.sleep(5) return "​a"​ end })
-file:​setvbuf("​full",​ 1) -- set buffer size to char +file:​setvbuf("​full",​ 1) -- 将缓冲区大小设定为1字符 
-file:​setTimeout(1) -- set buffer timeout to second +file:​setTimeout(1) -- 将缓冲超时时间设定为1 
--- this will time out before trying to read the 2nd char +-- 在尝试读取第二个字符之前就会超时 
-local a, b = file:​read(1,​ 1) -- read 1 char, then read 1 char again+local a, b = file:​read(1,​ 1) --读取一个字符,紧接着再读取一个字符
 ``` ```
  
-- `b:​seek([whence:​string],​ [offset:​number])`+- `b:​seek([whence:​string],​ [offset:​number])` ​  
 +  从`whence`开始移动IO流位置,共移动`offset`字节,两个参数都是可选的。`whence`默认为"​cur"​,'​offset'​默认为0。 
 +  可用的`whence`值: 
 +  - "​cur"​ 从当前位置开始。 
 +  - "​set"​ 从IO流的开始位置。 
 +  - "​end"​ 从IO流的结束位置。 
 +  返回在IO流中查找操作的结果(可能为失败)。
  
-  Moves the stream position by `offset` bytes from `whence`, both optional params. `whence` defaults to "​cur",​ and `offset` defaults to 0. +接口方法
-  Valid `whence` values: +
-  - "​cur"​ from the current position. +
-  - "​set"​ from the start of the stream. +
-  - "​end"​ from the end of the stream. +
-  Returns the result of the seek operation on the stream (which may fail). +
- +
- +
-Interface Methods+
 ----------- -----------
  
-The following methods are expected to be implemented on the buffered streams passed to `buffer.new`+下列方法应当在打算传给`buffer.new`的带缓冲IO流上实现。
- +
-- `close() ok, reason` +
- +
-  Close handles, release resources, disconnect -- and return success +
- +
-- `write(arg: string) ok, reason` +
- +
-  Write `arg` as bytes, assume a string of plain unformatted chars. Return falsey and reason on failure. +
- +
-- `read(n: number) ok, reason` +
- +
-  Return `n` bytes, and **not** `n` unicode-aware chars. Assume your data is binary data and let the buffer library manage the mode and the unicode string packaging (if applicable). Note that this is exactly how the [[api:​filesystem|filesystem]] library operates.The caller assumes there is more data to read until `nil` is returned. A empty string or a string shorter than `n` chars long is a valid return, but the caller may assume there is more data to request until `nil` is returned. +
- +
-- `seek([whence:​ string], [offset: number]) [offset from start] or falsey, reason` +
- +
-  Refer to `b:seek()` for details. In short, move the stream position to `offset` from `whence`, and return the `offset` from the start of the stream of the position after the seek operation. Note that `seek("​cur",​ 0)` is a valid request, typical of the caller wanting to determine the current position of the stream. Your stream is not required to support `seek`, in such case (or in any case of failure) you should return nil, and the reason (as a string) for the failure.+
  
 +- `close() ok, reason`  ​
 +  关闭句柄,释放资源,断开连接。并返回是否成功。  ​
 +\\
 +- `write(arg: string) ok, reason`  ​
 +  以字节形式写入`arg`,假定提供的是不加修饰的未格式化字符。失败时返回假值和原因。  ​
 +\\
 +- `read(n: number) ok, reason`  ​
 +  返回`n`个字节,而**不是**`n`个考虑Unicode的字符。我们假设你的数据为二进制数据,并且让buffer库管理IO模式与Unicode字符串打包(如果可用)。请注意这就是[[api:​filesystem|filesystem]]库的工作方式。直到返回`nil`前,此方法的调用者都会假定还有更多数据可读取。空字符串或长度短于`n`的字符串也是合法返回值,但调用者可能假定在返回`nil`前仍可请求更多数据。  ​
 +\\
 +- `seek([whence:​ string], [offset: number]) [offset from start] or falsey, reason`  ​
 +  请查看`b:​seek()`以获取细节。简而言之,从`whence`起将IO流位置移动`offset`,并返回从IO流开始位置到seek操作结束后的位置之间的`offset`值。请注意,`seek("​cur",​ 0)`也是合法请求,被用于调用者想获取IO流当前位置的情况下。你的自定义IO流不需要一定支持`seek`,这种情况下(以及任何失败情况下)你需要返回nil和失败原因(以字符串形式)。
  
-Examples+样例
 ----------- -----------