BlitzMax/Modules/Streams/Streams
流用于以顺序方式读取或写入数据。
BlitzMax 支持许多类型的流,包括标准文件流(用于读取和写入文件)、银行流(用于读取和写入银行)以及 字节序流(用于交换流数据的字节顺序)。
流通常使用 OpenStream、ReadStream 或 WriteStream 创建。但是,某些类型的流提供自己的创建流方法。例如,银行流使用 CreateBankStream 命令创建。
OpenStream、ReadStream 和 WriteStream 都需要一个 url 参数,该参数用于“定位”流。url 通常是一个字符串值。
如果 url 包含字符串“::”,则表示正在指定流 协议。如果不是,则假定 url 是一个简单的文件名。
外部模块可以向系统添加自己的流协议,使您能够将流用于各种用途。例如,“incbin::” 协议允许您从一个二进制文件读取数据,该文件已使用 Incbin 命令嵌入到应用程序中。
其他协议包括“http::” 用于通过网络读取和写入数据,“littleendian::” 和 “bigendian::” 用于交换流的字节顺序。
要写入流,请使用一个“Write”样式命令,例如 WriteByte。
要从流中读取,请使用一个“Read”样式命令,例如 ReadByte。
某些类型的流(例如,文件流和银行流)支持 随机访问。这意味着您可以使用 SeekStream 命令修改流中下一个读或写的位置。您还可以使用 StreamPos 命令查看您在这些流中的位置。
完成使用流后,您应始终使用 CloseStream 关闭它。如果未这样做,可能会导致资源泄漏,或阻止流在将来成功打开。
流抛出的基本异常类型
流在发生读取错误时抛出的异常类型
当流操作无法读取足够字节时,通常会抛出 TStreamReadException。例如,如果流 ReadInt 方法无法读取 4 个字节,它将抛出 TStreamReadException。
流在发生写入错误时抛出的异常类型
当流操作无法写入足够字节时,通常会抛出 TStreamWriteException。例如,如果流 WriteInt 方法无法写入 4 个字节,它将抛出 TStreamWriteException。
基本输入/输出类型
要创建自己的流类型,您应扩展 TStream 并至少实现以下方法。
您还应确保您的流能够处理对 Close 方法的多次调用。
- Eof
- Pos
- Size
- Seek
- Flush
- Close
- Read
- Write
方法 Eof()
描述: 获取流文件结束状态
返回值: 文件结束时为 True,否则为 False
信息: 对于可寻址流(如文件流),Eof 通常在文件位置等于文件大小时返回 True。这意味着无法从流中读取更多字节。但是,您仍然可以写入字节,在这种情况下,文件将“增长”。
对于通信类型的流(如套接字流),如果流因某种原因而关闭(无论是在本地还是由远程主机关闭),Eof 将返回 True。在这种情况下,无法再从流中读取或写入字节。
方法 Pos()
描述: 获取可寻址流的位置
返回值: 流位置(以字节偏移量表示),如果流不可寻址,则返回 -1
方法 Size()
描述: 获取可寻址流的大小
返回值: 可寻址流的大小(以字节为单位),如果流不可寻址,则返回 0
方法 Seek( pos )
描述: 寻址到可寻址流中的位置
返回值: 新的流位置,如果流不可寻址,则返回 -1
方法 Flush()
描述: 刷新流
信息: 刷新所有内部流缓冲区。
方法 Close()
描述: 关闭流
信息: 刷新所有内部流缓冲区后关闭流。
方法 Read( buf:Byte Ptr,count )
描述: 从流中读取至少 1 个字节
返回值: 成功读取的字节数
信息: 如果由于 IO 缓冲而无法读取至少一个字节,此方法可能会“阻塞”。
如果此方法返回 0,则流已到达文件末尾。
方法 Write( buf:Byte Ptr,count )
描述: 写入至少 1 个字节到流中
返回: 成功写入的字节数
信息: 如果由于 IO 缓冲而无法写入至少一个字节,此方法可能会“阻塞”。
如果此方法返回 0,则流已到达文件末尾。
TStream
[edit | edit source]数据流类型
TStream 扩展 TIO 以提供用于将各种类型的值读入和写出流的方法。
请注意,处理字符串的方法 - ReadLine、WriteLine、ReadString 和 WriteString - 假设字符串在流中以字节表示。将来,将添加一个功能更强大的 TextStream 类型,它能够以多种格式解码文本流。
- ReadBytes
- WriteBytes
- SkipBytes
- ReadByte
- WriteByte
- ReadShort
- WriteShort
- ReadInt
- WriteInt
- ReadLong
- WriteLong
- ReadFloat
- WriteFloat
- ReadDouble
- WriteDouble
- ReadLine
- WriteLine
- ReadString
- WriteString
TStream: 方法
[edit | edit source]方法 ReadBytes( buf:Byte Ptr,count )
描述: 从流中读取字节
信息: ReadBytes 从流中读取 count 个字节到 buf 指定的内存块中。
如果 count 个字节没有成功读取,则会抛出 TStreamReadException。这通常是由于文件结束造成的。
方法 WriteBytes( buf:Byte Ptr,count )
描述: 将字节写入流
信息: WriteBytes 将 count 个字节从 buf 指定的内存块写入流。
如果 count 个字节没有成功写入,则会抛出 TStreamWriteException。这通常是由于文件结束造成的。
方法 SkipBytes( count )
描述: 跳过流中的字节
信息: SkipBytes 从流中读取 count 个字节并将其丢弃。
如果 count 个字节没有成功读取,则会抛出 TStreamReadException。这通常是由于文件结束造成的。
方法 ReadByte()
描述: 从流中读取一个字节
返回: 读取的值
信息: 如果无法读取值(可能是由于文件结束),则会抛出 TStreamReadException。
方法 WriteByte( n )
描述: 将一个字节写入流
信息: 如果无法写入值(可能是由于文件结束),则会抛出 TStreamWriteException。
方法 ReadShort()
描述: 从流中读取一个短整型(两个字节)
返回: 读取的值
信息: 如果无法读取值(可能是由于文件结束),则会抛出 TStreamReadException。
方法 WriteShort( n )
描述: 将一个短整型(两个字节)写入流
信息: 如果无法写入值(可能是由于文件结束),则会抛出 TStreamWriteException。
方法 ReadInt()
描述: 从流中读取一个整型(四个字节)
返回: 读取的值
信息: 如果无法读取值(可能是由于文件结束),则会抛出 TStreamReadException。
方法 WriteInt( n )
描述: 将一个整型(四个字节)写入流
信息: 如果无法写入值(可能是由于文件结束),则会抛出 TStreamWriteException。
方法 ReadLong:Long()
描述: 从流中读取一个长整型(八个字节)
返回: 读取的值
信息: 如果无法读取值(可能是由于文件结束),则会抛出 TStreamReadException。
方法 WriteLong( n:Long )
描述: 将一个长整型(八个字节)写入流
信息: 如果无法写入值(可能是由于文件结束),则会抛出 TStreamWriteException。
方法 ReadFloat#()
描述: 从流中读取一个浮点数(四个字节)
返回: 读取的值
信息: 如果无法读取值(可能是由于文件结束),则会抛出 TStreamReadException。
方法 WriteFloat( n# )
描述: 将一个浮点数(四个字节)写入流
信息: 如果无法写入值(可能是由于文件结束),则会抛出 TStreamWriteException。
方法 ReadDouble!()
描述: 从流中读取一个双精度浮点数(八个字节)
返回: 读取的值
信息: 如果无法读取值(可能是由于文件结束),则会抛出 TStreamReadException。
方法 WriteDouble( n! )
描述: 将一个双精度浮点数(八个字节)写入流
信息: 如果无法写入值(可能是由于文件结束),则会抛出 TStreamWriteException。
方法 ReadLine$()
描述: 从流中读取一行文本
信息: 从流中读取字节,直到读取换行符(ASCII 码 10)或空字符(ASCII 码 0),或者检测到文件结束。
回车符(ASCII 码 13)会静默忽略。
读取的字节以字符串形式返回,不包括任何终止换行符或空字符。
方法 WriteLine( str$ )
描述: 将一行文本写入流
返回: 如果成功写入行,则为 True,否则为 False
信息: 将字节序列写入流(str 中的每个字符一个),然后是行终止序列 "~r~n"。
方法 ReadString$( length )
描述: 从流中读取字符
返回: 由从流中读取的 length 个字节组成的字符串
信息: 如果无法读取所有字节,则会抛出 TStreamReadException。
方法 WriteString( str$ )
描述: 将字符写入流
信息: 如果无法写入所有字节,则会抛出 TStreamWriteException。
TStreamWrapper
[edit | edit source]实用程序流包装器类型
TStreamWrapper '包装' 现有流,将所有 TIO 方法调用重定向到包装的流。
这对于编写修改现有流行为的流 '过滤器' 很有用。
请注意,Close 方法会导致底层流关闭,这并不总是可取的。如果需要,您应该使用 NOP 版本覆盖 Close。
- SetStream
TStreamWrapper: 方法
[edit | edit source]方法 SetStream( stream:TStream )
描述: 设置底层流
信息: 设置要 '包装' 的流。对该流的所有 TIO 方法调用都将重定向到 stream。
TCStream
[edit | edit source]标准 C 文件流类型
- OpenFile
- CreateWithCStream
TCStream: 函数
[edit | edit source]函数 OpenFile:TCStream( path$,readable,writeable )
描述: 从 'C' 文件名创建 TCStream
函数 CreateWithCStream:TCStream( cstream,mode )
描述: 从 'C' 流句柄创建 TCStream
TStreamFactory
[edit | edit source]基本流工厂类型
流工厂由 OpenStream、ReadStream 和 WriteStream 函数使用,用于根据 'url 对象' 创建流。
Url 对象通常是字符串,在这种情况下,url 被分成两个部分 - 协议和路径。它们由双冒号字符串 "::" 分隔。
要创建自己的流工厂,您应该扩展 TStreamFactory 类型并实现 CreateStream 方法。
要安装您的流工厂,只需使用 'New' 创建它的实例即可。
- CreateStream
TStreamFactory: 方法
[edit | edit source]方法 CreateStream:TStream( url:Object,proto$,path$,readable,writeable )
描述: 根据 url 对象创建流
信息: 扩展 TStreamFactory 的类型必须实现此方法。
url 包含传递给 OpenStream、ReadStream 或 WriteStream 的原始 url 对象。
如果 url 是一个字符串,则 proto 包含 url 协议 - 例如,"incbin::myfile" 中的 "incbin" 部分。
如果 url 是一个字符串,则 path 包含 url 的其余部分 - 例如,"incbin::myfile" 中的 "myfile" 部分。
如果 url 不是字符串,则 proto 和 path 都将为 Null。
函数
[edit | edit source]OpenStream
[edit | edit source]函数 OpenStream:TStream( url:Object,readable=True,writeable=True )
描述: 打开一个用于读写操作的流
返回: 流对象
信息: 所有由 OpenStream、ReadStream 或 WriteStream 创建的流最终都应该使用 CloseStream 关闭。
Function ReadStream:TStream( url:Object )
描述: 打开一个流用于读取
返回: 流对象
信息: 所有由 OpenStream、ReadStream 或 WriteStream 创建的流最终都应该使用 CloseStream 关闭。
示例:
' readstream.bmx ' opens a read stream to the blitzbasic.com website and ' dumps the homepage to the console using readline and print in=ReadStream("http::blitzbasic.com") If Not in RuntimeError "Failed to open a ReadStream to file http::www.blitzbasic.com" While Not Eof(in) Print ReadLine(in) Wend CloseStream in
Function WriteStream:TStream( url:Object )
描述: 打开一个流用于写入
返回: 流对象
信息: 所有由 OpenStream、ReadStream 或 WriteStream 创建的流最终都应该使用 CloseStream 关闭。
示例:
' writestream.bmx ' opens a write stream to the file mygame.ini and ' outputs a simple text file using WriteLine out=WriteStream("mygame.ini") if not out RuntimeError "Failed to open a WriteStream to file mygame.ini" WriteLine out,"[display]" WriteLine out,"width=800" WriteLine out,"height=600" WriteLine out,"depth=32" WriteLine out,"" WriteLine out,"[highscores]" WriteLine out,"AXE=1000" WriteLine out,"HAL=950" WriteLine out,"MAK=920" CloseStream out print "File mygame.ini created, bytes="+FileSize("mygame.ini")
Function Eof( stream:TStream )
描述: 获取流文件结束状态
返回值: 如果流处于文件末尾则为 True
Function StreamPos( stream:TStream )
描述: 获取可定位流的当前位置
返回值: 当前流位置,如果流不可定位则为 -1
Function StreamSize( stream:TStream )
描述: 获取可定位流的当前大小
返回值: 当前流大小(以字节为单位),如果流不可定位则为 -1
Function SeekStream( stream:TStream,pos )
描述: 设置可定位流的流位置
返回值: 新的流位置,如果流不可定位则为 -1
Function FlushStream( stream:TStream )
描述: 刷新流
信息: FlushStream 将任何未完成的缓冲数据写入 stream。
Function CloseStream( stream:TStream )
描述: 关闭流
信息: 所有流在不再需要时都应关闭。关闭流也会在关闭之前刷新流。
Function ReadByte( stream:TStream )
描述: 从流中读取一个字节
返回值: 一个字节值
信息: ReadByte 从 stream 中读取一个字节。如果可用数据不足,则抛出 TStreamReadException。
Function ReadShort( stream:TStream )
描述: 从流中读取一个短整型
返回值: 一个短整型值
信息: ReadShort 从 stream 中读取 2 个字节。如果可用数据不足,则抛出 TStreamReadException。
Function ReadInt( stream:TStream )
描述: 从流中读取一个整型
返回值: 一个整型值
信息: ReadInt 从 stream 中读取 4 个字节。如果可用数据不足,则抛出 TStreamReadException。
Function ReadLong:Long( stream:TStream )
描述: 从流中读取一个长整型
返回值: 一个长整型值
信息: ReadLong 从 stream 中读取 8 个字节。如果可用数据不足,则抛出 TStreamReadException。
Function ReadFloat#( stream:TStream )
描述: 从流中读取一个单精度浮点数
返回值: 一个单精度浮点数
信息: ReadFloat 从 stream 中读取 4 个字节。如果可用数据不足,则抛出 TStreamReadException。
Function ReadDouble!( stream:TStream )
描述: 从流中读取一个双精度浮点数
返回值: 一个双精度浮点数
信息: ReadDouble 从 stream 中读取 8 个字节。如果可用数据不足,则抛出 TStreamWriteException。
Function WriteByte( stream:TStream,n )
描述: 向流中写入一个字节
信息: WriteByte 向 stream 中写入一个字节。如果字节无法写入,则抛出 TStreamWriteException
Function WriteShort( stream:TStream,n )
描述: 向流中写入一个短整型
信息: WriteShort 向 stream 中写入 2 个字节。如果无法写入所有字节,则抛出 TStreamWriteException
Function WriteInt( stream:TStream,n )
描述: 向流中写入一个整型
信息: WriteInt 向 stream 中写入 4 个字节。如果无法写入所有字节,则抛出 TStreamWriteException
Function WriteLong( stream:TStream,n:Long )
描述: 向流中写入一个长整型
信息: WriteLong 向 stream 中写入 8 个字节。如果无法写入所有字节,则抛出 TStreamWriteException
Function WriteFloat( stream:TStream,n# )
描述: 向流中写入一个单精度浮点数
信息: WriteFloat 向 stream 中写入 4 个字节。如果无法写入所有字节,则抛出 TStreamWriteException
Function WriteDouble( stream:TStream,n! )
描述: 将一个 Double 写入流
信息: WriteDouble 将 8 个字节写入 stream。如果无法写入所有字节,则会抛出 TStreamWriteException
Function ReadString$( stream:TStream,length )
描述: 从流中读取一个字符串
返回值: 长度为 length 的字符串
信息: 如果无法读取所有字节,则会抛出 TStreamReadException。
Function WriteString( stream:TStream,str$ )
描述: 将一个字符串写入流
信息: str 中的每个字符都将写入 stream。
如果无法写入所有字节,则会抛出 TStreamWriteException。
Function ReadLine$( stream:TStream )
描述: 从流中读取一行文本
返回值: 一个字符串
信息: 从 stream 中读取字节,直到遇到换行符(ASCII 码 10)或空字符(ASCII 码 0),或者检测到文件结尾。
回车符(ASCII 码 13)将被静默忽略。
读取的字节以字符串形式返回,不包括任何终止换行符或空字符。
Function WriteLine( stream:TStream,str$ )
描述: 将一行文本写入流
返回: 如果成功写入行,则为 True,否则为 False
信息: 将字节序列写入流(str 中的每个字符一个),然后是行终止序列 "~r~n"。
Function LoadString$( url:Object )
描述: 从流中加载一个字符串
返回值: 一个字符串
信息: 打开指定的 url 以供读取,并将结果流中的每个字节(直到文件结束)读入一个字符串。
如果无法读取流,则会抛出 TStreamReadException。
Function SaveString( str$,url:Object )
描述: 将一个字符串保存到流
信息: 打开指定的 url 以供写入,并将 str 的每个字符写入结果流。
如果无法写入所有字节,则会抛出 TStreamWriteException。
Function LoadByteArray:Byte[]( url:Object )
描述: 从流中加载一个字节数组
返回值: 一个字节数组
信息: 打开指定的 url 以供读取,并将结果流中的每个字节(直到文件结束)读入一个字节数组。
Function SaveByteArray( byteArray:Byte[],url:Object )
描述: 将一个字节数组保存到流
信息: 打开指定的 url 以供写入,并将 byteArray 的每个元素写入结果流。
如果无法写入所有字节,则会抛出 TStreamWriteException。
Function CopyStream( fromStream:TStream,toStream:TStream,bufSize=4096 )
描述: 将流内容复制到另一个流
信息: CopyStream 将字节从 fromStream 复制到 toStream,直到 fromStream 达到文件结尾。
如果无法写入所有字节,则会抛出 TStreamWriteException。
Function CopyBytes( fromStream:TStream,toStream:TStream,count,bufSize=4096 )
描述: 将字节从一个流复制到另一个流
信息: CopyBytes 将 count 个字节从 fromStream 复制到 toStream。
如果无法读取所有字节,则会抛出 TStreamReadException,如果无法写入所有字节,则会抛出 TStreamWriteException。
Function CasedFileName$(path$)
描述: 如果存在,则从不区分大小写的文件路径返回区分大小写的文件名。