本章专门介绍 Visual Basic 中的输入和输出。 Visual Basic 中的输入和输出基于流。
流是与输入和输出一起使用的对象。 流是字节序列的抽象,例如文件,输入/输出设备,进程间通信管道或 TCP / IP 套接字。 在 Visual Basic 中,我们有一个Stream
类,它是所有流的抽象类。 还有一些其他类可以从 Stream 类派生而来,从而使编程更加容易。
MemoryStream
MemoryStream
是用于处理计算机内存中数据的流。
Option Strict On
Imports System.IO
Module Example
Sub Main()
Dim ms As Stream = New MemoryStream(6)
ms.WriteByte(9)
ms.WriteByte(11)
ms.WriteByte(6)
ms.WriteByte(8)
ms.WriteByte(3)
ms.WriteByte(7)
ms.Position = 0
Dim rs As Integer
rs = ms.ReadByte()
Do While rs <> -1
Console.WriteLine(rs)
rs = ms.ReadByte()
Loop
ms.Close()
End Sub
End Module
我们用MemoryStream
将六个数字写入存储器。 然后,我们读取这些数字并将其打印到控制台。
Dim ms As Stream = New MemoryStream(6)
该行创建并初始化一个容量为六个字节的MemoryStream
对象。
ms.Position = 0
我们使用Position
属性将光标在流中的位置设置为开头。
ms.WriteByte(9)
ms.WriteByte(11)
ms.WriteByte(6)
...
WriteByte()
方法在当前位置的当前流中写入一个字节。
Do While rs <> -1
Console.WriteLine(rs)
rs = ms.ReadByte()
Loop
在这里,我们从流中读取所有字节并将其打印到控制台。
ms.Close()
最后,我们关闭流。
$ ./memory.exe
9
11
6
8
3
7
示例的输出。
StreamReader
& StreamWriter
StreamReader
从字节流中读取字符。 默认为 UTF-8 编码。 StreamWriter
以特定编码将字符写入流。
Option Strict On
Imports System.IO
Module Example
Sub Main()
Dim file As String
file = "languages"
Try
Dim stream As StreamReader
stream = New StreamReader(file)
Console.WriteLine(stream.ReadToEnd())
Catch e As IOException
Console.WriteLine("Cannot read file.")
End Try
End Sub
End Module
我们有一个名为 Languages 的文件。 我们从该文件中读取字符并将其打印到控制台。
Dim stream As StreamReader
stream = New StreamReader(file)
StreamReader
以文件名作为参数。
Console.WriteLine(stream.ReadToEnd())
ReadToEnd()
方法读取所有字符到流的末尾。
$ cat languages
Python
Visual Basic
PERL
Java
C
C#
$ ./readfile.exe
Python
Visual Basic
PERL
Java
C
C#
当前目录中有一个语言文件。 我们将文件的所有行打印到控制台。
在下一个示例中,我们将对行进行计数。
Option Strict On
Imports System.IO
Module Example
Sub Main()
Dim file As String
Dim count As Integer
file = "languages"
Try
Dim stream As StreamReader
stream = New StreamReader(file)
While Not (stream.ReadLine() Is Nothing)
count += 1
End While
Catch e As IOException
Console.WriteLine("Cannot read file.")
End Try
Console.WriteLine("There are {0} lines", count)
End Sub
End Module
计算文件中的行数。
While Not (stream.ReadLine() Is Nothing)
count += 1
End While
在 While 循环中,我们使用ReadLine()
方法从流中读取一行。 它从流返回一行,如果到达输入流的末尾,则返回 Nothing。
以下是StreamWriter
的示例。
Option Strict On
Imports System.IO
Module Example
Sub Main()
Dim mstream As New MemoryStream()
Dim swriter As New StreamWriter(mstream)
swriter.Write("ZetCode, tutorials for programmers.")
swriter.Flush()
Dim sreader As New StreamReader(mstream)
Console.WriteLine(sreader.ReadToEnd())
sreader.Close()
End Sub
End Module
在前面的示例中,我们将字符写入内存。
Dim mstream As New MemoryStream()
创建了MemoryStream
。
Dim swriter As New StreamWriter(mstream)
StreamWriter
类将内存流作为参数。 这样,我们将要写入内存流。
swriter.Write("ZetCode, tutorials for programmers.")
swriter.Flush()
我们写一些文字给作家。 Flush()
清除当前写入器的所有缓冲区,并使所有缓冲的数据写入基础流。
Dim sreader As New StreamReader(mstream)
Console.WriteLine(sreader.ReadToEnd())
现在,我们创建流读取器的实例,并读取回写的所有内容。
FileStream
FileStream
类在文件系统上的文件上使用流。 此类可用于读取文件,写入文件,打开文件和关闭文件。
Option Strict On
Imports System.IO
Imports System.Text
Module Example
Sub Main()
Dim fstream As New FileStream("author", FileMode.Append)
Dim bytes As Byte() = New UTF8Encoding().GetBytes("Фёдор Михайлович Достоевский")
fstream.Write(bytes, 0, bytes.Length)
fstream.Close()
End Sub
End Module
我们用俄语 azbuka 将一些文本写入当前工作目录中的文件。
Dim fstream As New FileStream("author", FileMode.Append)
创建一个FileStream
对象。 第二个参数是打开文件的模式。 附加模式将打开文件(如果存在)并查找到文件末尾,或创建一个新文件。
Dim bytes As Byte() = New UTF8Encoding().GetBytes("Фёдор Михайлович Достоевский")
我们使用俄语 azbuka 中的文本创建字节数组。
fstream.Write(bytes, 0, bytes.Length)
我们将字节写入文件流。
XmlTextReader
我们可以使用流来读取 XML 数据。 XmlTextReader
是在 Visual Basic 中读取 XML 文件的类。 该类是仅转发和只读的。
我们有以下 XML 测试文件。
<?xml version="1.0" encoding="utf-8" ?>
<languages>
<language>Python</language>
<language>Ruby</language>
<language>Javascript</language>
<language>C#</language>
</languages>
Option Strict On
Imports System.IO
Imports System.Xml
Module Example
Sub Main()
Dim file As String
file = "languages.xml"
Try
Dim xreader As New XmlTextReader(file)
xreader.MoveToContent()
Do While xreader.Read()
Select Case xreader.NodeType
Case XmlNodeType.Element
Console.Write(xreader.Name & ": ")
Case XmlNodeType.Text
Console.WriteLine(xreader.Value)
End Select
Loop
xreader.Close()
Catch e As IOException
Console.WriteLine("Cannot read file.")
Catch e As XmlException
Console.WriteLine("XML parse error")
End Try
End Sub
End Module
此 Visual Basic 程序从先前指定的 XML 文件中读取数据并将其打印到终端。
Dim xreader As New XmlTextReader(file)
创建一个XmlTextReader
对象。 它以文件名作为参数。
xreader.MoveToContent()
MoveToContent()
方法移至 XML 文件的实际内容。
Do While xreader.Read()
该行从流中读取下一个节点。
Case XmlNodeType.Element
Console.Write(xreader.Name & ": ")
Case XmlNodeType.Text
Console.WriteLine(xreader.Value)
在这里,我们打印元素名称和元素文本。
Catch e As XmlException
Console.WriteLine("XML parse error")
我们检查 XML 解析错误。
$ ./readxml.exe
language: Python
language: Ruby
language: Javascript
language: C#
示例输出。
文件和目录
.NET 框架提供了其他类,我们可以使用这些类来处理文件和目录。
File
类是更高级别的类,具有用于文件创建,删除,复制,移动和打开的共享方法。 这些方法使工作更加轻松。
Option Strict On
Imports System.IO
Module Example
Sub Main()
Try
Dim sw As StreamWriter
sw = File.CreateText("cars")
sw.WriteLine("Toyota")
sw.WriteLine("Skoda")
sw.WriteLine("BMW")
sw.WriteLine("Volkswagen")
sw.WriteLine("Volvo")
sw.Close()
Catch e As IOException
Console.WriteLine("IO error")
End Try
End Sub
End Module
在示例中,我们创建了一个 cars 文件,并在其中写入了一些汽车名称。
sw = File.CreateText("cars")
CreateText()
方法创建或打开一个文件,用于写入 UTF-8 编码的文本。 它返回一个StreamWriter
对象。
sw.WriteLine("Toyota")
sw.WriteLine("Skoda")
...
我们向流写入两行。
Option Strict On
Imports System.IO
Module Example
Sub Main()
If File.Exists("cars")
Console.WriteLine(File.GetCreationTime("cars"))
Console.WriteLine(File.GetLastWriteTime("cars"))
Console.WriteLine(File.GetLastAccessTime("cars"))
End If
File.Copy("cars", "newcars")
End Sub
End Module
在第二个示例中,我们显示了File
类的其他五个共享方法。
If File.Exists("cars")
Exists()
方法确定指定的文件是否存在。
Console.WriteLine(File.GetCreationTime("cars"))
Console.WriteLine(File.GetLastWriteTime("cars"))
Console.WriteLine(File.GetLastAccessTime("cars"))
我们得到指定文件的创建时间,上次写入时间和上次访问时间。
File.Copy("cars", "newcars")
Copy()
方法复制文件。
My.Computer.FileSystem
是和对象,它提供用于处理驱动器,文件和目录的属性和方法。
Option Strict On
Imports System.IO
Module Example
Sub Main()
Try
My.Computer.FileSystem.CreateDirectory("temp")
My.Computer.FileSystem.CreateDirectory("newdir")
My.Computer.FileSystem.MoveDirectory("temp", "temporary")
Catch e As IOException
Console.WriteLine("Cannot create directories")
Console.WriteLine(e.Message)
End Try
End Sub
End Module
我们将使用上述对象中的两种方法。
My.Computer.FileSystem.CreateDirectory("temp")
CreateDirectory()
方法创建一个新目录。
My.Computer.FileSystem.MoveDirectory("temp", "temporary")
MoveDirectory()
方法为指定的目录提供一个新名称。
DirectoryInfo
和Directory
具有用于创建,移动和枚举目录和子目录的方法。
Option Strict On
Imports System.IO
Module Example
Dim subDir As IO.DirectoryInfo
Dim dir As New IO.DirectoryInfo("../io")
Dim fileName As String
Dim files As String() = Directory.GetFiles("../io")
Dim dirs As DirectoryInfo() = dir.GetDirectories()
Sub Main()
For Each subDir In dirs
Console.WriteLine(subDir.Name)
Next
For Each fileName In files
Console.WriteLine(fileName)
Next
End Sub
End Module
我们使用DirectoryInfo
类遍历特定目录并打印其内容。
Dim dir As New IO.DirectoryInfo("../io")
我们将显示该目录(io)的内容。
Dim files As String() = Directory.GetFiles("../io")
我们使用共享的GetFiles()
方法获取 io 目录的所有文件。
Dim dirs As DirectoryInfo() = dir.GetDirectories()
我们得到所有目录。
For Each subDir In dirs
Console.WriteLine(subDir.Name)
Next
在这里,我们遍历目录并将其名称打印到控制台。
For Each fileName In files
Console.WriteLine(fileName)
Next
在这里,我们遍历文件数组并将其名称打印到控制台。
$ ./showcontents.exe
newdir
temp
temporary
../io/append.exe
../io/append.vb
../io/append.vb~
../io/author
../io/cars
...
示例的输出。