简介 有经验的 Visual Basic 开发人员最初可能会认为Visual 中的变化使本来已经熟悉的领域变得陌生而难以驾驭其实过去开发的成果仍然可以使用例如Visual Basic 运行时文件 I/O 方法就是大家比较熟悉的同样以前曾涉猎过 FileSystemObject 对象的开发人员也可以继续在这一领域畅游尽管公共语言运行时领域可能让人感到陌生并且到处都是以对象为中心的怪物但同时它提供的功能却极具诱惑力例如 FileSystemWatcher 或 FileIOPermissions 类中的新功能
事实上唯一让 Visual Basic NET 开发人员望而却步的是如何从这三种方法中进行选择对许多应用程序而言对文件和目录进行操作是最重要的但是 Visual Basic NET 所提供的灵活方法可能会使人感到困惑并且会提出下列问题Visual Basic NET 提供什么样的文件访问?何时使用 FileSystemObject 对象?使用公共语言运行时中的方法有哪些好处?是否需要专门使用一种方法?如何选择方法?
Visual Basic NET 中的文件方法
让我们先看看 MicrosoftVisualBasic 命名空间这可以为那些被全新的 NET 领域吓坏的开发人员带来一些安慰和信心命名空间包含许多熟悉的函数和方法除了部分名称有少许改动外大部分名称仍保持不变如 DirInputPrintSeekWrite 等等
在选择运行时函数时主要应考虑写入文件或从文件中收集的信息的类型Visual Basic NET 为三种类型的文件提供了访问方法每种方法适用于一种特定的数据类型二进制顺序和随机
二进制访问允许您以任意方式存储和访问数据这种方法对于变长字段尤为有用
随机访问允许您以记录的方式存储和访问信息这种方法假定记录是等长的顺序访问允许您在文本文件中读取和写入字符串
这些不同类型的文件访问所使用的函数发生了一些变化最显着的变化是用 FilePut/FilePutObject 和 FileGet/FileGetObject 函数代替 Put 和 Get 函数在 Visual Basic NET 中FilePut 和 FileGet 映射到 Put 和 Get 函数FilePutObject 和 FileGetObject 用于将 Object 类型(等价于 Visual Basic 早期版本中的 Variant 类型)的对象写入文件
例如下面是 Visual Basic 的代码
Dim Person As Variant
If IdentifyPeopleByName Then
Person = 我的姓名
Else
Person =
EndIf
Put # Person
在 Visual Basic NET 中变为
FileOpen( c:\testtxt OpenModeBinary)
Dim Person As Object
If IdentifyPeopleByName Then
Person = 我的姓名
Else
Person =
EndIf
FilePutObject( Person)
FileClose()
总之对于有经验的 Visual Basic 程序员来说这一方面应该很容易掌握下表列出了 Visual Basic NET 中用于文件和目录操作的函数并提供了介绍各个函数的相应主题的链接
函数 | 说明 | CurDir返回表示当前目录的 String 值
Dir返回 String 值
表示与指定模式或文件属性相匹配的文件名
目录名或文件夹名
或者表示驱动器的卷标
EOF当为随机输入或顺序输入而打开的文件到达末尾时
返回 Boolean 值 True
FileClose将 I/O 写入到使用 FileOpen 函数打开的文件
FileCopy复制文件并保留原文件
FileDateTime返回 Date 值
表明最近一次修改文件的日期和时间
FileLen返回 Long 值
表明文件的长度(字节)
FileOpen打开用于输入或输出的文件
FreeFile返回 Integer 值
指定 FileOpen 函数可以使用的下一个文件的编号
GetAttr返回 FileAttribute 值
表示文件
文件夹或目录的属性
Input从打开的顺序文件读取数据并将该数据分配给变量
InputString返回 String 值
包含在 Input 或 Binary 模式下打开的文件中的字符
LineInput从打开的顺序文件中读取一行并将其分配给 String 变量
Loc返回 Long 值
指定在打开的文件中的当前读/写位置
LOF返回 Long 值
表示使用 FileOpen 函数打开的文件的大小(字节)
Print将显示格式的数据写入顺序文件
PrintLine将显示格式的数据写入顺序文件
并以回车符结束
Seek返回 Long 值
指定在使用 FileOpen 函数打开的文件中的当前读/写位置
或为使用 FileOpen 函数打开的文件中的下一个读/写操作设置位置
SetAttr设置文件的属性信息
如 ReadOnly
Hidden
Directory
Archive 等等
Write将数据写入顺序文件
通常使用 Input 函数从文件中读取使用 Write 函数写入的数据
WriteLine将数据写入顺序文件
并以回车符结束
优点和缺点
Visual Basic NET 运行时提供的函数有两个主要优点即为开发人员所熟悉并且易于使用Visual Basic NET 的核心功能仍然保留其为人所熟悉直观和灵活的特点同时提供了舒适的 NET 开发环境
同样将在 Visual Basic 早期版本中编写的程序升级到 NET或者创建能够与在 Visual Basic 早期版本中编写的应用程序正常交互的应用程序也相对简单
Visual 函数还提供二进制文件访问为使用变长字段时提供了更好的选择而 FileSystemObject 对象(将在下一节介绍)则没有此功能
最后一点在从 Visual Basic NET 中使用 Visual Basic NET 内置文件 I/O 函数时没有需要特别注意的事项(如需要导入命名空间)
Visual Basic NET 文件 I/O 函数仅支持 StringDateIntegerLongSingleDouble 和 Decimal 写入类型以及这些类型的结构和数组这是使用这些函数时的一个缺点此外不能将类序列化因此在这些情况下直接使用 SystemIO 类性能可能会更佳
代码示例
如以下各例所示使用 Visual Basic 运行时方法进行文件和目录操作是开发人员所熟悉的
以下示例将检查文件是否存在如果存在则使用 FileCopy 函数将其复制到新文件
Private Sub CopyFiles()
Dim checkFile As String
checkFile = Dir$(c:\testtxt)
If checkFile = testtxt
FileCopy c:\testtxt c:\newtxt
End If
End Sub
以下示例使用 FilePut 函数将数据写入文件FilePut 函数与 Visual Basic 早期版本的 Put 函数相对应结构 CustomerRecord 的三个记录被写入文件
Structure CustomerRecord
Public OrderNumber As Integer
Public Name As String
Public OrderDate As Date
End Structure
Sub WriteData()
Dim MyRecord As CustomerRecord
Dim RecordNumber As Integer
Dim RecordDate As Date
打开文件进行随机访问
FileOpen( C:\TESTFILEtxt OpenModeBinary)
For RecordNumber = To 循环 次
MyRecordOrderNumber = RecordNumber 定义 OrderNumber
MyRecordOrderDate = RecordDate 定义 OrderDate
MyRecordName = 我的姓名 & RecordNumber 创建字符串
FilePut( MyRecord) 将记录写入文件
Next RecordNumber
FileClose()
End Sub
FileSystemObject
与 MicrosoftVisualBasic 命名空间提供的函数和方法类似Visual Basic 早期版本的用户也应当熟悉 FileSystemObject 对象在 Visual Basic NET 中仍然可以使用此对象
FileSystemObject (FSO) 模型将文件目录和驱动器表示为 COM 对象每个对象都有自己的属性和方法您可以创建和操纵这些对象并使用这些对象的属性来查找信息如目录内容文件大小对象的创建时间等等通过创建和访问 FileSystemObject 对象的实例可以访问表示系统文件目录和驱动器的对象
FSO 对象模型位于 Microsoft 脚本运行时类型库 (Scrrundll) 中支持通过 TextStream 对象创建和操纵文本文件有关详细信息请参阅 TextStreamFileStream 类围绕文件提供一个数据流允许对文件系统进行同步或异步读写操作以及缓沖输入和输出以改善性能信息被写入缓沖区只有当缓沖区已满或调用 Close 方法时缓沖区中的内容才会被写入文件
优点和缺点
FSO 的主要优点是它可以将许多文件 I/O 函数集合到单个对象中通过创建该对象的实例可以访问对象的方法和属性
下表列出了 FSO 对象模型的基本组件并提供了与相应主题对应的链接这些主题列出了适用于创建和操纵文件驱动器及目录的属性和方法
对象 | 说明 | FileSystemObject创建与删除驱动器
文件夹和文件
获取其信息并对其进行常规操作
与此对象相关的许多方法都与其他对象中的相应方法相同
Drive获取关于连接到系统的驱动器的信息
如可用空间及其共享名称
File创建
删除或移动文件
以及在系统中查询文件的名称
路径和其他信息
Folder创建
删除或移动文件夹
以及在系统中查询文件夹的名称
路径和其他信息
TextStream读写文本文件
FSO 对象模型也适用于线程它提供了一个用于异步 I/O 的构造函数如当使用 BeginRead 和 BeginWrite 方法时该函数可使主线程继续允许用户稍后再处理数据多个 I/O 请求可以同时挂起
但是FSO 也有一些不足之处如上所述它只能对文本文件进行操作要操纵二进制文件您必须使用指针指向内存地址或字节数组但 FSO 对象不支持此操作
此外当您读取或写入大量内容时存储在缓沖区中的信息可能会产生很高的内存命中率还有您不能管理许可权限或文件和文件夹属性
实现方法
可以使用 Object Browser(对象浏览器)来查看 FSO 模型的对象集合属性方法事件和常数要在 Object Browser(对象浏览器)中查看 FSO必须首先向 Microsoft 脚本运行时类型库添加一个引用
向 Microsoft 脚本运行时类型库添加引用
在 Project(项目)菜单上单击 Add Reference(添加引用)
在 COM 选项卡上选择 Microsoft Scripting Runtime(Microsoft 脚本运行时)单击 Select(选择)然后单击 OK(确定)
现在FSO 将显示在 Object Browser(对象浏览器)中的 InteropScripting 节点内
使用 FileSystemObject 进行编程
使用 CreateObject 方法创建一个 FileSystemObject 对象
将一个变量定义为 FileSystemObject 对象例如
Dim MyFileStream as ScriptingNew FileSystemObject
对新创建的对象使用相应的方法
访问对象的属性
代码示例
以下示例使用 FileSystemObject 对象的实例来读取文件并写入文件内容
Public Class UsesScripting
Public Shared Sub Main()
Dim fileSystem As New ScriptingFileSystemObject()
Dim file As ScriptingTextStream
file = fileSystemOpenTextFile(c:\testtxt _
ScriptingIOModeForReading False_
ScriptingTristateTristateUseDefault)
Dim contents As String = fileReadAll()
ConsoleWriteLine(contents)
fileClose()
End Sub
End Class
框架类
SystemIO 命名空间包含 File 和 Directory 类它们可以提供操纵文件和目录所需的基本功能由于所有方法都是静态的或是这些对象的共享成员因此您可以直接使用它们而无需先创建类的实例
下表列出了 File 类方法
方法 | 说明 | AppendText创建 StreamWriter 的一个实例
将 UTF
编码文本附加到现有文件
Copy将现有文件复制到新文件
Create以指定的完全限定路径创建文件
CreateText创建或打开一个新文件
用于编写 UTF
编码文本
Delete删除指定文件
Exists返回 Boolean 值
表明指定文件是否存在
GetAttributes返回完全限定路径的文件的 FileAttributes
GetCreationTime返回 Date
表示指定文件的创建时间
GetLastAccessTime返回 Date
表示最近一次访问指定文件的时间
GetLastWriteTime返回 Date
表示最近一次写入指定文件的时间
Move将指定文件移到新位置
提供选项以指定新的文件名
Open打开指定路径的 FileStream
OpenRead打开现有文件以进行读取
OpenText打开现有的 UTF
编码文本文件以进行读取
OpenWrite打开现有文件以进行写入
SetAttributes设置指定路径中的文件的指定 FileAttributes
SetCreationTime设置指定文件的创建日期和时间
SetlastAccessTime设置最近一次访问指定文件的日期和时间
SetLastWriteTime设置最近一次写入指定文件的日期和时间
下表列出了附加到 Directory 类的方法
方法 | 说明 | CreateDirectory按 path 的规定创建所有目录和子目录
Delete删除指定目录
Exists返回 Boolean 值
表明指定目录是否存在
GetCreationTime返回 Date
表示指定目录的创建时间
GetCurrentDirectory返回 String
表示应用程序的当前工作目录
GetDirectories返回 String
表示指定目录中的子目录名称
GetDirectoryRoot返回 String
表示指定路径的卷信息
根信息或同时表示这两种信息
GetFiles返回 String
表示指定目录中的文件名
GetFileSystemEntries返回 String
表示指定目录中所有文件和子目录的名称
GetLastAccessTime返回最近一次访问指定目录的日期和时间
GetLastWriteTime返回 Date
表示最近一次写入指定目录的时间
GetLogicalDrives返回 String
表示计算机的逻辑驱动器的名称
GetParent返回 String
表示指定路径的父目录
Move将目录及其内容移到新位置
SetCreationTime设置指定目录的创建日期和时间
SetCurrentDirectory将应用程序的当前工作目录设置为指定目录
SetLastAccessTime设置最近一次访问指定目录的日期和时间
SetLastWriteTime设置最近一次写入指定目录的日期和时间
优点和缺点
公共语言运行时能够生成丰富的类库例如除基本文件 I/O 外SystemIO 命名空间还提供许多服务如 FileSystemWatcher 类允许您监视对文件的更改以及 FileInfo 和 DirectoryInfo 类使您可以收集有关指定文件或目录的信息有关详细信息请参阅 FileSystemWatcherFileInfo 和 DirectoryInfo
同样公共语言运行时也提供 FileIOPermission 类允许您控制对文件和目录的访问这对于使用 Web 窗体的开发人员尤为重要因为默认情况下Web 窗体在一个名为 ASPNET 的特定本地用户环境中运行而 ASPNET 是作为 ASPNET/框架安装的一部分而创建的当此类应用程序请求访问资源时此请求在该用户的环境中进行不过在默认情况下ASPNET 用户只拥有有限的权限使他们无法执行从 Web 应用程序写入文件等操作
公共语言运行时也能够与其他 NET 语言兼容(如 Visual C#?)并有助于保持应用程序之间的一致性这一点对于企业级的开发尤为重要
对于刚刚开始熟悉这些新方法的 Visual Basic 程序员而言不熟悉公共语言运行时可能会遇到一些困难如果您是其中一员您可能更倾向于使用您所熟知的方法
实现方法
如上所述许多 框架类(如 FileIOPermission)对于使用文件和目录进行工作的 Visual Basic 开发人员都十分有用Imports 语句允许您在不使用完全限定名称的情况下引用命名空间中的类
代码示例
以下示例使用 StreamReader 类来读取文本文件的内容
Imports System
Imports SystemIO
Function ReadTextFile(ByVal path As String) As String
Dim sr As SystemIOStreamReader
Dim Contents As String
sr = New StreamReader(path)
Contents = srReadToEnd()
srClose()
Return Contents
End Function
以下代码与前面的示例顺序相反它使用与 StreamWriter 类相同的方法来写入文本文件
Imports System
Imports SystemIO
Sub WriteTextFile(ByVal path As String ByVal value As String)
Dim sr As StreamWriter
Dim Contents As String
sr = New StreamWriter(path)
srWrite(value)
srClose()
End Sub
以下示例演示了如何使用 FileSystemWatcher 类来监视目录的变化它声明 FileSystemWatcher 类的一个实例提供要监视的路径指示要监视的内容然后创建一个事件处理程序来监视新文件的创建
Imports System
Imports SystemIO
Imports SystemXML
Imports SystemXMLSerialization
Class WatchForNewFiles
Shared Sub Main()
Dim fw As New SystemIOFileSystemWatcher()
要监视的路径
fwPath = C:\
监视文件
fwNotifyFilter = SystemIONotifyFiltersFileName
fwIncludeSubdirectories = True
添加事件处理程序以监视文件创建
AddHandler fwCreated _
New SystemIOFileSystemEventHandler(AddressOf OnFileEvent)
fwEnableRaisingEvents = True
ConsoleReadLine()
End Sub
新文件创建时生成的事件
Shared Sub OnFileEvent(ByVal source As Object ByVal e As _
SystemIOFileSystemEventArgs)
ConsoleWriteLine(在 C: 中创建的新文件 & eFullPath)
End Sub
End Class
以下示例说明了如何使用公共语言运行时类来保存 Visual Basic NET 类可以使用 BinaryFormatter 和 BinaryWriter/Binary Reader 类来保存使用这种方法效率较高但可读性略差也可以使用 XMLSerializer 类和 FileStream 类使用这种方法移植性较强且易于读取但效率较低
Imports System
Imports SystemIO
Imports SystemXml
Imports SystemXmlSerialization
Public Module Module
Public Class class
Public classvar As Integer
End Class
Sub Main()
Try
Dim Result As Object
创建并初始化要保存的类(序列化)
Dim myclass As New class()
myclassclassvar =
创建序列化程序
Dim xs As New XmlSerializer(GetType(class))
创建文件流
Dim FStream As New IOFileStream(c:\xyztxt _
IOFileModeOpenOrCreate)
使用序列化程序编写类
xsSerialize(FStream myclass)
将文件流的位置重置到开始位置
Fstreamseek( IOSeekOriginBegin)
通过还原序列化到对象中来完成在类中的读取操作
Result = xsDeserialize(FStream)
FStreamClose()
将文件流作为文本打开以 XML 格式读取/打印类
consoleWriteLine(readxml())
Catch e As Exception
consoleWriteLine(eToString)
End Try
End Sub
Function ReadXML() As String
Dim MyReader As StreamReader = FileOpenText(c:\xyztxt)
Dim str As String
Dim al As ArrayList = New ArrayList()
Do
str = MyReaderReadLine()
If str <> Nothing Then
ReadXML &= str & VBcrlf
End If
Loop Until str = Nothing
Return ReadXML
End Function
End Module
总结
在这些方法中不管是使用 Visual Basic NET 运行时方法采用 FileSystemObject 对象还是使用 NET 框架函数根据不同的情况和应用程序每种方法都各有利弊对于需要处理大型文件的应用程序而言使用公共语言运行时函数要比使用 FSO 方法好对于要与在早期版本中 Visual Basic 编写的应用程序进行交互的应用程序而言使用 Visual Basic 运行时方法可以达到更佳性能在每种情况下您都需要评估应用程序的需求运行环境以及您驾驭不同方法的能力
正如您所看到的从早期版本至今Visual Basic 不断展示出新的功能程序员的视野也不断得到扩大对于大多数人来说最好是将这些方法结合起来从而可以根据应用程序的特定需要来选择不同的方法您既可以继续使用熟悉的方法也可以进一步探索新方法