1 / 61

第 16 章 文件应用

第 16 章 文件应用. 有关的内容: 3 个文件系统的可视化的标准控件 ( 驱动器 , 目录 , 文件列表 ) Windows 通用文件对话框控件,用于指定或选择文件(打开或保存) 操作文件的语句和函数(学习不同类型文件的打开、关闭、读、写等) 和文件系统有关的语句和函数 使用文件系统对象来访问文件(学习有关对象的属性和方法). 文件的类型. 文件就是保存在磁盘上的字节,不同类型的文件有不同的结构,即字节之间的关系,以及每个字节表示什么内容(是整数、字符串还是数据记录等),根据这些结构我们将文件的类型划分为三类。 顺序文件

kana
Download Presentation

第 16 章 文件应用

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第16章 文件应用 有关的内容: • 3个文件系统的可视化的标准控件(驱动器, 目录, 文件列表) • Windows通用文件对话框控件,用于指定或选择文件(打开或保存) • 操作文件的语句和函数(学习不同类型文件的打开、关闭、读、写等) • 和文件系统有关的语句和函数 • 使用文件系统对象来访问文件(学习有关对象的属性和方法)

  2. 文件的类型 • 文件就是保存在磁盘上的字节,不同类型的文件有不同的结构,即字节之间的关系,以及每个字节表示什么内容(是整数、字符串还是数据记录等),根据这些结构我们将文件的类型划分为三类。 • 顺序文件 • 顺序文件保存为一个连续块,块中的字节代表的都是文本字符,读取和写入都是字符或字符串类型数据(ANSI字符),而且都是按照顺序进行的。 • 随机文件 • 当一个文本文件中含有多条记录,而且每条记录有固定统一的长度时,可以实现记录的随机访问。不一定是纯文本。 • 二进制文件 • 二进制文件则适用于读写任意结构的文件。二进制文件中的字节可以代表任何东西。只有精确地知道数据是如何写到文件中后,才可能对它进行正确的读取或检索。

  3. 文件访问的步骤 • 使用Open语句打开文件, 指定文件号和存取方式 • 从文件中读取数据到变量中 • 使用或处理变量中的数据, 或者保存变量中的数据到其它文件中 • 文件操作结束, 使用Close语句关闭文件

  4. 打开顺序文件 Open filename For [Input|Output|Append] As [#] FileNumber • FileNumber指定一个有效的文件号,1~511,使用FreeFile函数可以得到下一个可用的文件号,此后对文件的访问基于该文件号。 可执行以下操作: • Input:从文件中读取字符 • Output:向文件输出字符,文件原来的内容丢失 • Append:将字符追加到文件的最后,原内容保留 Input操作的前提条件是文件必须存在; Output和Append则可以自动先创建再打开。

  5. 读取顺序文件 • Input()函数,读取任意数量的字符到变量中 Text1.Text = Input(LOF(filenum), filenum) 第一个参数指读取字符数量,第二个参数指定文件号 • Input#语句,从文件中读取数据到一个或多个变量中,必须是指定格式或由Write#语句写入的数据 Input #1, MyName, MyNumber • LineInput#语句, 从文件中读取一行,给字符串变量 Line Input #filenum, LineString Text1.Text = Text1.Text + LineString+Chr(13) + Chr(10)

  6. 从文件中读取一行 • 【例】读取文件test.txt,结果置于一个文本框中。 Open "d:\test.txt" For Input As 1 Do Until EOF(1) Line Input #1, NextLine Text1.Text = Text1.Text + NextLine + vbCrLf Loop Close #1 • 尽管Line Input # 到达回车换行时它会识别行尾,但是,当它把整行字符串读入变量时,不会包括回车换行。如果要保留该回车换行,必须在代码中添加。

  7. 写入顺序文件 • Print#语句,向文件中写入一行 Print #filenumber, [outputlist] 第一个参数指定文件号, 第二个参数为表达式 Print #1, "This is a test" Print #1, ‘写入一个空行 Print #1, StuNum; Tab; StuName Print #1, Spc(5) ; "Hello" Print #1, Tab(10) ; "Hello" • Write#语句, 将数据写入文件(区别数据类型) Write #filenumber, [outputlist] Write #1, “Hello World”, 234 Write #1, strName • 与Print的区别: • 值之间使用逗号分隔 • 字符串使用引号括起

  8. 修改顺序文件 • 对于顺序文件没有提供直接修改的方法,如果要修改一个文件的内容,一般的步骤是: • 1)以Input方式打开文件; • 2)读取文件的内容到某个变量中,关闭文件; • 3)修改变量的值; • 4)以Output方式打开文件; • 5)将变量值写入到文件中,关闭文件结束。

  9. 关闭顺序文件 • Close#语句 Close #1 ' 关闭1号文件 Close #1, #2, #4 ' 关闭1号、2号和4号文件 Close ' 关闭所有打开的文件 • 执行Close语句后,文件与其文件号之间的关联将终结,同样的文件号可以在后面的程序中继续使用。 • 当对文件进行写入操作时,只有使用了关闭命令,才会真正将缓冲区的文件内容写入到磁盘的文件中,同时所有与该文件相关联的缓冲区空间都被释放。

  10. 访问顺序文件示例1 • 【例】读取任意指定的文本文件,进行如下处理:删除一个段落中的所有硬回车,只保留段落与段落之间的回车符(假设:某一行的第一个字符前有四个半角空格,就代表一个段落的开始)。

  11. 访问顺序文件示例 Dim strLine As String ‘ 用于保存每次读出的一行文本 Dim fileNo As Integer ' 当前打开文件的文件号 Text1.Text = "" Text2.Text = "" fileNo = FreeFile ' 获取当前可用的文件号 Open “d:\a.txt” For Input As fileNo Do While Not EOF(fileNo) ' 按行循环读出文件内容 Line Input #fileNo, strLine Text1.Text = Text1.Text & strLine & vbCrLf If Left(strLine, 4) = " " Then ' 行前有四个空格 Text2.Text = Text2.Text & vbCrLf & strLine Else Text2.Text = Text2.Text & strLine End If Loop Close #fileNo

  12. 访问顺序文件示例 ' 将处理后的文本写入文件 Open “d:\a.txt” For Output As fileNo Print #fileNo, Text2.Text Close #fileNo

  13. 访问顺序文件示例2 • 【例】将两个文本文件进行合并。如:1.txt + 2.txt -> 3.txt Dim f_in As Integer, f_out As Integer, str As String f_out = FreeFile() '打开合并后的文件用于写 Open App.Path & "\all.txt" For Output As f_out '打开第一个文件用于读,并写入到合并文件中 f_in = FreeFile() Open App.Path & "\1.txt" For Input As f_in Do While Not EOF(f_in) Line Input #f_in, str Print #f_out, str Loop Close #f_in '打开第二个文件用于读,并写入到合并文件中 Open App.Path & "\2.txt" For Input As f_in Do While Not EOF(f_in) Line Input #f_in, str Print #f_out, str Loop Close #f_in Close #f_out MsgBox "完成!"

  14. 访问顺序文件示例3 • 【例】进行全班考试成绩统计,计算平均分、最高分、最低分。成绩存放在score.txt文件中(以空格分开)。 Dim f1 As Integer, i As Integer, num As Integer, score(50) As Integer Dim str As String, strArray() As String num = 0 ‘计数,统计成绩个数 ‘打开分数文件,逐行读取并转换到数组中 f1 = FreeFile() Open App.Path & "\score.txt" For Input As f1 Do While Not EOF(f1) Line Input #f1, str ‘每行按照空格切分字符串, 切分结果在字符串数组strArray中 strArray = Split(str, " ") '全部分数转换后存放到score数组中 For i = 0 To UBound(strArray) score(num) = CInt(strArray(i)) num = num + 1 Next Loop Close f1

  15. 访问顺序文件示例3 min = 100 max = 0 For i = 0 To num - 1 sum = sum + score(i) If score(i) > max Then max = score(i) If score(i) < min Then min = score(i) '求各分数段人数 If score(i) < 60 Then c1 = c1 + 1 ElseIf score(i) < 70 Then c2 = c2 + 1 ElseIf score(i) < 80 Then c3 = c3 + 1 ElseIf score(i) < 90 Then c4 = c4 + 1 Else c5 = c5 + 1 End If Next avg = sum / num

  16. 文件长度和中文字符* • 获取文件长度 • 文件打开时:LOF(filenumber),如:LOF(1) • 文件没有打开是:FileLen(filename),如:FileLen(“c:\a.txt”) • 文件长度:返回的是文件中字节的个数,而不是字符个数 • 英文单字节编码系统(ANSI):一个字符就是一个字节 • 中英文混合编码系统(DBCS):中文两个字节,英文一个字节 • 统一双字节编码系统(Unicode):每个字符都占用两个字节,VB所有内部操作以此为基础 • 但是目前的文本文件基本上是采用DBCS。VB根据长度读取文件时,有两种方式: • Input(20, 1):这是按照字符的个数读取,然后自动转换为Unicode。 • InputB(20, 1):按字节的个数读取,不转换为Unicode(需要用StrConv函数) • 同样,字符串长度有两种方式: • Len(“你好Hello”) 结果是7(字符的个数) • LenB (“你好Hello”) 结果是14(字节的个数)

  17. 访问随机文件 • 随机文件由记录构成,每个记录由定长的字段构成,这样很容易随机找到某个记录的某个字段 • 随机文件中的字节构成相同的一些记录,每个记录包含一个或多个字段。 • 为了完整地定义随机文件中的记录,我们需要用户自定义类型。因为所有记录是同样的长度,所以所有字符串字段都必须使用定长字符串类型。例如,课程记录由三个字段组成的自定义类型Course来描述,每条记录的总长度为32个字节。 Type Course Name As String * 20 TeacherName As String * 10 ClassHours As Integer End Type

  18. 打开随机文件 • 随机文件打开后既可以写,同时又允许读,这和顺序文件每次打开只能执行某一种操作不同,这种优越性就是固定了每个记录的长度所带来的。 Open filename [For Random] As number Len = reclength • 表达式Len = reclength指定了记录的长度,每次读写操作以该长度为单位进行。一般指定reclength为自定义类型变量的长度,可利用Len函数取得 • 如果reclength比记录的实际长度短,则出错。比实际长度长,可写,但浪费了空间 Reclen = Len(Stu) Open file1 For Random As filenum len = Reclen RecCount = LOF(filenum) / Reclen

  19. 读取记录 Get filenumber, recnumber, varname • filenumber:打开的顺序文件的文件号 • recnumber:要读取的记录号,如省略则随上次记录向下 • varname: 读入的变量名 • 例如,将第10条记录取出,存放到变量Stu中: Get FileNum, 10, Stu

  20. 写入记录 Put [#]filenumber, [recnumber], varname • Recnumber:指定记录号。它是一个可选项,如果指定了记录号,就代表从指定的记录号所在位置开始写,如果省略则表示在上一个put语句紧邻的下一个记录位置开始写入,实质上记录号指定了记录写入文件的位置。 • Varname:记录变量,该变量数据将写入文件。 • 比如将变量myClass作为文件的第三个记录写入进去: myClass.Name = "VB程序设计" myClass.TeacherName = "张三" myClass.ClassHours = 40 Put #FileNum, 3, myClass

  21. 替换记录 • 替换随机文件中的记录,即修改记录原来的内容。替换操作不会改变文件的结构和长度。 • 仍然使用Put语句,如修改第10条记录的姓名字段: Get FileNum, 10, Stu Stu.Name = “Jonh” Put FileNum, 10, Stu

  22. 添加记录 • 在任何位置都可以添加新记录,即写入记录,而不论该位置之前是否存在非空记录。 • 如果需要紧邻上一记录,则只要保证记录号增1。设Reccount为原来的记录数: Reccount = Reccount + 1 Put FileNum, Reccount, Stu • LOF(filenumber):可以返回文件的大小,可以用于计算随机文件的记录个数: recCount = LOF(1) / recLength + 1

  23. 删除记录 • 删除记录会改变文件长度,以上简单操作无法完成。 • 需要使用一个临时文件,将原文件中的有效记录读取出来,写入到临时文件中,再将临时文件改名即可: • Get:使用Get语句从原文件中读记录 • Put:使用Put语句写部分记录到临时文件 • Kill:使用Kill语句删除原文件 • Name… As …:将临时文件换名为原文件名

  24. 访问随机文件示例 • 【例】编写程序,完成一个学期教学计划的安排,包括:从课程列表框中选择一门课程,从教师列表框选择任课教师,输入课时,然后添加到课程文件中。 • 为了提高灵活性,课程名和教师名存放在一个文本文件中,程序执行前,用户可以自行修改。

  25. 访问随机文件示例 ‘定义教学计划的记录类型 Private Type Course Name As String * 20 TeacherName As String * 10 ClassHours As Integer End Type ‘窗体加载事件中进行界面的初始化。首先初始化课时组合框 cboHours.AddItem "24" cboHours.AddItem "32" cboHours.AddItem "40" cboHours.AddItem "50" cboHours.AddItem "60" cboHours.ListIndex = 3

  26. 访问随机文件示例 Dim strLine As String ‘ 从课程文件中读取所有课程 Open App.Path & "\class.txt" For Input As 1 Do While Not EOF(1) Line Input #1, strLine lstClass.AddItem strLine Loop Close (1) lstClass.ListIndex = 0 ‘ 从教师文件中读取所有教师 Open App.Path & "\teacher.txt" For Input As 1 Do While Not EOF(1) Line Input #1, strLine lstTeacher.AddItem strLine Loop Close (1) lstTeacher.ListIndex = 0

  27. 访问随机文件示例 ' 添加课程信息到随机文件中 Private Sub cmdAdd_Click() Dim recNo As Integer Dim recLength As Integer Dim myCourse As Course myCourse.Name = lstClass.Text ' 准备要写入文件的变量 myCourse.TeacherName = lstTeacher.Text myCourse.ClassHours = CInt(cboHours.Text) recLength = Len(myCourse) ' 计算记录的长度 Open App.Path & "\course.dat" For Random As 1 Len = recLength recNo = LOF(1) / recLength + 1 ‘ 计算当前新记录的记录号 Put 1, recNo, myCourse Close (1) End Sub

  28. 访问二进制文件 • 二进制文件中的字节可以代表任何数据(如非定长记录格式)。只有精确地知道数据是如何写到文件中后,才可能对它进行正确的读取或检索,否则只能靠人工的猜测和推理。因此对于不想直接公开的内容,程序员通常会以二进制文件来保存。二进制访问需要了解每个字节代表的含义,只有掌握了文件格式后,才能编写程序正确地读出文件。 • 打开文件 Open filename For Binary As number • 读写文件 Get|Put number , recnumber, varname

  29. 文件系统的有关函数 • 与驱动器、目录和文件有关的操作,比如创建目录,复制、删除文件,文件改名等。这些函数不涉及文件内容的操作。 • 如何读出文件内容,或写一个文件以后再介绍。

  30. 改变当前驱动器 ChDrive drive • drive 必选参数,指定驱动器名, 为“”则不变 • drive 如果含多个字符, 则取第一个 例: ChDrive “D”

  31. 取当前目录 CurDir [(drive)] • drive:字符串表达式, 指定驱动器名 • 无参数, 或drive=“”, 返回当前驱动器路径 例: MyPath=CurDir MyPath=CurDir(“C”) MyPath=CurDir(“D”)

  32. 改变当前目录 ChDir path • path 必选参数,指定默认目录名, 可包含驱动器名 • 如果不指定驱动器, 则在当前驱动器上改变目录 例: ChDir “Vbbooks” ChDir “D:\Temp” 改变驱动器的默认目录, 但不改变默认驱动器

  33. 得到当前可执行文件路径 App.Path • App对象是一个全局对象, 不需要声明, 指定应用程序的有关信息 • Path, 返回应用程序执行文件路径 • Title, 返回应用程序在任务列表中的标题 • EXTName, 返回应用程序的执行文件名

  34. 建立和删除目录 MkDir path • path 必选参数,指定新目录名, 可包含驱动器名 • 如果不指定驱动器, 则在当前驱动器上建目录 RmDir path • 同上 例: MkDir “wxm” RmDir “D:\data” 删除目录, 必须是该目录是一个空目录, 没有文件

  35. 删除文件 Kill filename • filename 必选参数,指定文件名, 可包含路径 • filename 可以是包含通配符的字符串 例: Kill “D:\temp\test.dat” Kill “D:\temp\*.tmp” 删除文件, 必须是该文件没有正在使用

  36. 设置文件属性 SetAttr pathname, attributes • pathname 必选参数,指定文件名 • attributes 常数或数值表达式, 指定文件属性, 属性取值有:vbNormal, vbReadOnly, vbHidden, vbSystem, 例: SetAttr “D:\data.txt”, vbReadOnly + vbHidden 设置文件属性, 必须是该文件没有正在使用(打开) 读取文件属性,使用GetAttr(pathname)函数

  37. 文件拷贝 FileCopy source, destination Dim SourceFile, DestinationFile SourceFile = “名单.txt" DestinationFile = “名单2.txt“ FileCopy SourceFile, DestinationFile

  38. 文件改名 Name oldpathname As newpathname 重新命名文件并将其移动到一个不同的目录或文 件夹中。 • Name 可跨驱动器移动文件。 • Name 不能创建新文件、目录或文件夹 • 参数不能包括多字符(*) 和单字符 (?) 的统配符

  39. DIR函数 返回指定参数条件的文件名或目录名 Dir[(pathname[, attributes])] • Pathname:目录名,可以含有通配符 • Attributes:文件属性 • vbNormal:0 • vbReadOnly:1只读 • vbHidden:2隐藏 • VbSystem:4系统 • vbVolume:8卷标 • vbDirectory:16包含目录

  40. DIR函数 MyFile = Dir(“*.TXT”, vbHidden) ‘取第一个隐含TXT文件名 MyFile = Dir ‘取下一个 MyPath = “c:\” ‘取出C驱动器下所有一级目录名并显示 MyName = Dir(MyPath, vbDirectory) Do While MyName <> "" If MyName <> "." And MyName <> ".." Then If GetAttr(MyPath & MyName) = vbDirectory Then Debug.Print MyName End If MyName = Dir End If Loop

  41. 其它函数和语句 • FileDateTime(Filename):文件创建或最后修改日期和时间 • FileLen(Filename):返回打开前文件的长度(字节数 • FreeFile():返回一个可用的文件号 • EOF(filenumber):返回布尔值表明是否到达文件尾 • LOF(filenumber):返回文件的大小 • Loc(filenumber):返回文件当前的读/写位置 • Seek(filenumber):返回文件的当前位置 • Seek filenumber, position:设置文件的当前位置,影响下一次的读/写操作

  42. 使用对象类访问文件 • 虽然以上列出的一系列语句或函数可以全面操作驱动器、目录或文件,但它们很分散,难于记忆和使用。 • VB提供了一个完整的对象模型,该模型中包含了与驱动器、目录和文件等元素完全对应的一组对象,利用各个对象的属性和方法可以方便地获取文件系统的信息、处理目录和文件、以及读写顺序文件。 • 这就是File System Object(FSO)对象模型

  43. File System Objects对象模型 FSO对象模型中主要的5个对象: • Drive对象:读取驱动器信息 • Folder对象:管理文件夹,读取文件夹信息 • Files对象:管理文件,读取文件信息 • TextStream对象:主要用于读写文件 • FileSystem Object对象:提供对驱动器、文件夹和文件的各种操作,核心对象。该对象建立在以上对象的基础之上,比如很多方法是复制了其它对象的方法,还提供方法创建生成以上对象。

  44. 使用类库(非可视化对象) • FSO对象不是一个可见的控件对象,不能通过部件添加到工程中,需要引用类库(Class Library) • 类库示对象类的集合,可以为开发者提供大量制作好的可以直接使用的对象 在工程中添加对象类引用 • “工程”菜单中,选择“引用”命令 • 选定类库名称左边的复选框 • 单击“确定”按钮

  45. 加载FSO对象模型 • FSO对象模型包含在一个称为Scripting的类型库中,此类型库位于Scrrun.Dll文件中。要使用该类型库,必须首先在工程中引用此文件,操作方法如下: • 执行【工程】→【引用】菜单命令,打开“引用”对话框; • 在对话框中的可引用类型库列表中选中“Microsoft Scripting Runtime”项并确定; • 使用“对象浏览器”可以查看其对象、集合、属性、方法、事件以及它的常数,同时在声明变量时,输入As关键字后,该类型库中的对象类型会自动显示在数据类型提示列表中。

  46. FileSystemObject对象 该对象是FSO对象模型中的核心对象,FSO编程 的主要步骤: (1) 在“工程|引用”中选择“Microsoft Scripting runtime” (2) 创建一个FileSystemObject对象 (3)通过读取新对象的属性值获取信息 (4)调用FileSystemObject对象中的方法来创建一个新的对象,如Files对象、Drive对象

  47. 创建一个FileSystemObject对象 方法一:使用New关键字 Dim oFSO as FileSystemObject ‘声明对象 Set oFSO = New FileSystemObject ‘创建对象 或 Dim oFSO as New FileSystemObject ‘声明并创建对象 方法二:使用CreateObject函数 Dim oFSO as FileSystemObject ‘声明对象 Set oFSO=CreateObject(“Scripting.FileSystemObject”) 对象其实就象C语言中的指针,声明时并没有空间,也没有内容,是一个空值。只有创建后才能使用(等同于让指针指向一个有意义的空间)

  48. 访问驱动器 【例】窗体加载后,输出系统各驱动器的容量和剩余可用空间。 Private Sub Form_Load() Dim objFso As New FileSystemObject Dim strInfo As String, d On Error Resume Next For Each d In objFso.Drives strInfo = d.DriveLetter & " : " strInfo = strInfo & " 全部空间=" & d.TotalSize strInfo = strInfo & " 可用空间=" & d.AvailableSpace Debug.Print strInfo Next End Sub

  49. FileSystemObject对象的属性 Drives属性:是一个驱动器对象的集合,即Drive对象 的集合。 Drive对象的主要属性有: • AvailableSpace:驱动器上的可用空间 • DriveLetter:驱动器号(只读) • DriveType:驱动器类型 • FileSystem:文件系统的类型 • FreeSpace:可用空间 • VolumnName:卷标名 • IsReady:是否准备好

  50. 使用FileSystemObject访问驱动器 • DriveExist方法:返回真存在,否则不存在oFSO.DriveExists(“d”) (2) GetDrive方法:返回一个指定的Drive对象 set oDrive = oFSO.GetDrive(“c:”) (3) GetDriveName方法:从指定的路径名中返回驱动器名,但不检查是否存在 oFSO.GetDriveName(“d:\vb6”)

More Related