文件
⒈ 文件结构
⑴ 字符(Character):是构成文件的最基本单位。
⑵ 字段(Field):也称域。字段由若干个字符组成,用来表示一项数据。
⑶ 记录(Record):由一组相关的字段组成。  

⒉ 文件种类
⑴ 根据数据性质,可分为程序文件和数据文件。
① 程序文件(Program File):这种文件存放的是可以由计算机执行的程序,包括源文件和可执行文件。
② 数据文件(Data File):数据文件用来存放普通的数据。

⑵ 数据文件(Data File):数据文件用来存放普通的数据。
① 顺序文件(Sequential File):顺序文件的结构比较简单,文件中的记录一个接一个地存放。
② 随机存取文件(Random Access Tile):又称直接存取文件,简称随机文件或直接文件。

⑶ 根据数据的编码方式,可以分为ASCII文件和二进制文件
① ASCII文件:又称文本文件,它以ASCII方式保存文件。这种文件可以用字处理软件建立和修改(必须按纯文本文件保存)。
② 二进制文件(Brinary File):以二进制方式保存的文件。二进制文件不能用普通的字处理软件编辑,占空间较小。


文件的打开与关闭
文件的打开(建立)----FileOpen函数
[格式]FileOpen(文件号,文件名,方式[,访问类型][,共享类型][,记录长度]
[说明]方式:用来指定文件的输入输出方式,包括:Output/顺序输出,Input/顺序输入,Append/顺序输出。
      访问类型:用来指定访问文件的类型,包括:Default打开读/写文件,Read/打开只读文件,Write/打开只写文件,ReadWrite打开读/写文件
      共享类型:可选。 包括:Default共享/同Shared,Shared任何机器上的任何进程都可以对该文件进行读写操作,LockRead不允许其他进程读该文件。LockWrite不允许其他进程写这个文件。Lock Read Write不允许其他进程读写这个文件。
      记录长度:可选。 不能超过32767B。

*为了满足不同的存取方式的需要,对同一个文件可以用几个不同的文件号打开,每个文件号有自己的一个缓冲区。对于不同的访问方式,可以使用不同的缓冲区。但是,当使用Output或Append方式时,必须先将文件关闭,才能重新打开文件。而当使用Input、Random或Binary方式时,不必关闭文件就可以用不同的文件号打开文件。

*FileOpen函数兼有打开文件和建立文件两种功能。

文件的关闭----FileClose函数
[格式]FileClose([文件号])
 *如果不使用FileClose函数关闭文件,则可能使某些需要写入的数据不能从内存(缓冲区)送入文件中。


文件操作语句和函数
文件指针
       文件被打开后,自动生成一个文件指针(隐含的),文件的读或写就从这个指针所指的位置开始。用Append方式打开一个文件后,文件指针指向文件的末尾,而如果用其他几种方式打开文件,则文件指针都指向文件的开头。完成一次读写操作后,文件指针自动移到下一个读写操作的起始位置,移动量的大小由FileOpen函数和读写语句中的参数共同决定。对于随机文件来说,其文件指针的最小移动单位是一个记录的长度,而顺序文件中文件指针移动的长度与它所读写的字符串的长度相同

文件指针的定位通过Seek函数来实现。
[格式] Seek(文件号[,位置])
[说明] ⑴ 对于用Input、Output或Append方式打开的文件,“位置”是从文件开头到“位置”为止的字节数,即执行下一个操作的地址,文件第一个字节的位置是1。对于用Random方式打开的文件,“位置”是一个记录号。
⑵ 在FileGet或FilePut函数中的记录号优先于由Seek函数确定的位置。此外,当“位置”为0或负数时,将产生出错信息“错误的记录号”。当Seek函数中的“位置”在文件尾之后时,对文件的写操作将扩展该文件。


其他语句和函数
⒈ FreeFile函数:得到一个在程序中没有使用的文件号。
⒉ Loc(文件号):Loc函数返回由“文件号”指定的文件的当前读写位置。
⒊ LOF(文件号):LOF函数返回给文件分配的字节数(即文件的长度)
⒋ EOF(文件号):EOF函数用来测试文件的结束状态。Do While Not EOF(1)。。。Loop


顺序文件的写操作
Print函数和PrintLine函数
[格式]Print(文件号,[[Spc(n)|Tab(n)][表达式表]]))把数据写入文件。
      PrintLine(文件号,[[Spc(n)|Tab(n)][表达式表]]))把数据写入文件,在行尾包含换行。
     Print函数的功能是:“文件号”的含义同前,数据被写入该文件号所代表的文件中。PrintLine函数与Print函数基本相同,唯
与Print函数有关的函数
⒈ Tab(n): Tab函数把光标移到由参数n指定的位置,从这个位置开始输出信息。
⒉ Spc(n):在Print的输出中,用Spc函数可以跳过n个空格。

编程序显示表格。
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Tpname, Tptel, TpAddr As String
        FileOpen(1, "d:/temp/test.txt", OpenMode.Output)    '注意该文件路径必须存在
        Dim x, y As Short
        Print(1, TAB(2), "姓名", TAB(10), "年龄", TAB(16), "职务")
        Print(1, TAB(24), "单位", TAB(32), "籍贯")
        PrintLine(1)
        PrintLine(1, TAB(2), "张得功", TAB(10), 25, TAB(16), "科长", _
        TAB(24), "劳动科", TAB(32), "北京")
        Print(1, TAB(2), "李得胜", TAB(10), 32, TAB(16), "处长", _
                TAB(24), "科研处", TAB(32), "上海")
        FileClose(1)
End Sub

⒊ Space(n):Space函数返回n个空格。
编写程序,用Print函数向文件中写入数据。
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Tpname, Tptel, TpAddr As String
        FileOpen(1, "d:/temp/tel.txt", OpenMode.Output)
        Tpname = InputBox("请输入姓名:", "数据输入")
        Tptel$ = InputBox("请输入电话号码:", "数据输入")
        TpAddr = InputBox("请输入地址:", "数据输入")
        FileClose(1)
End Sub

⒋ Write函数和WriteLine函数
[格式]Write(文件号,表达式表):把数据写入顺序文件中,Write不在行尾包含换行
      WriteLine(文件号,表达式表):把数据写入顺序文件中,WriteLine在行尾包含换行

在磁盘上建立一个电话号码文件,存放单位名称和该单位的电话号码。
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Unit, Tel As String
        FileOpen(1, "d:/temp/tel.txt", OpenMode.Output)
        Unit = InputBox("请输入单位名称:")
        While UCase(Unit) <> "DONE"
            Tel = InputBox("请输入电话号码:")
            Write(1, Unit, Tel)
            WriteLine(1)
            Unit = InputBox$("请输入单位名称:")
        End While
        FileClose(1)
        End
End Sub

从键盘上输入4个学生的数据,然后把它们存放到磁盘文件中。

Structure stu
Dim stname As String
Dim num As Integer
Dim age As Integer
Dim addr As String
End StructurePrivate Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim CL As String = Chr(13) & Chr(10)
        Static stud() As stu
        Dim n, i As Short
        n = InputBox("请输入学生人数:")
        FileOpen(1, "d:/temp/stu_list.txt", OpenMode.Output)
        ReDim stud(n)
        For i = 1 To n
            stud(i).stname = InputBox("请输入姓名:")
            stud(i).num = InputBox("请输入学号:")
            stud(i).age = InputBox("请输入年龄:")
            stud(i).addr = InputBox("请输入住址:")
            Write(1, stud(i).stname, stud(i).num, stud(i).age, stud(i).addr)
            Write(1, CL)    '在一行的尾部加上一个回车-换行
        Next i
        FileClose(1)
        End
  End Sub

顺序文件的读操作
⒈ Input(文件号,变量):Input函数从一个顺序文件中每次只读取一个数据项,并把数据项赋给程序变量。 常用来读取由Print或Write函数写入的文件。也可用于随机文件。

把前面建立的学生数据文件(Stu_list.txt)读到内存,并在输出窗口中显示出来。

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim n, I, j As Short
        Dim S As String = "      "
        Dim studInfo As String
        Dim CL As String = Chr(13) & Chr(10)
        FileOpen(1, "d:/temp/stu_list.txt", OpenMode.Input)
        Debug.WriteLine("")
        Debug.WriteLine("姓  名" & S & "学号" & S & "年龄" & S & "住址" & CL)
        Do While Not EOF(1)
            Input(1, studInfo)
            If studInfo <> CL Then
                Debug.Write(studInfo & S)
            Else
                Debug.Write(CL)
            End If
        Loop
        Debug.WriteLine(CL)
        FileClose(1)
End Sub

编写程序,对数值数据排序

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Static number() As Integer
        Dim n, i, j, temp As Short
        FileOpen(1, "d:/temp/sortdata.txt", OpenMode.Input)
        Input(1, n)
        ReDim number(n)
        For i = 1 To n
            Input(1, number(i))
 Next i
        Debug.WriteLine("")For i = n To 2 Step -1
            For j = 1 To i - 1
                If number(j) > number(j + 1) Then
                    temp = number(j + 1)
                    number(j + 1) = number(j)
                    number(j) = temp
                End If
            Next j
        Next i
        FileClose(1)
        For i = 1 To n
            Debug.Write(number(i) & " ")
            If i Mod 10 = 0 Then Debug.WriteLine("")
        Next i
        Debug.WriteLine("")
  End Sub

2.字符串变量=LineInput(文件号):LineInput函数从顺序文件中读取一行的全部字符,直至遇到回车符为止,并把它赋给一个字符串变量。

把一个磁盘文件的内容读到内存并在文本框中显示出来,然后把该文本框中的内容存入另一个磁盘文件。
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Aspect, Whole As String
        Dim CL As String = Chr(13) + Chr(10)
        FileOpen(1, "d:/temp/smtext1.txt", OpenMode.Input)
        Do While Not EOF(1)
            Aspect = LineInput(1)
            Whole = Whole & Aspect & CL
        Loop
        TextBox1.Text = Whole$
        FileClose(1)
        FileOpen(1, "d:/temp/smtext2.txt", OpenMode.Output)
        Print(1, TextBox1.Text)
        FileClose(1)
  End Sub

 

随机文件
随机文件有以下特点:
⑴ 随机文件的记录是定长记录,只有给出记录号n,才能通过[(n-1)×记录长度]计算出该记录与文件首记录的相对地址。因此,在用FileOpen函数打开文件时必须指定记录的长度。
⑵ 每个记录划分为若干个字段,每个字段的长度等于相应的变量的长度。
⑶ 各变量(数据项)要按一定格式置入相应的字段。
⑷ 打开随机文件后,既可读也可写。

随机文件的打开与读写操作
⒈ 随机文件的写操作:FilePut(文件号,变量[,记录号])
⒉ 随机文件的读操作:FileGet(文件号,变量[,记录号])

建立一个随机存取的工资文件,然后读取文件中的记录。
Structure RecordType
        <VBFixedString(10)> Dim EmName As String
        <VBFixedString(16)> Dim Wunit As String
        Dim Age As Short
        Dim Salary As Short
End Structure

Dim recordvar As RecordType
Dim recLen As Integer = Len(recordvar)
Dim recordnumber As Long

'执行输入数据及写盘操作

Sub File_Write()
        Dim aspect As Char
        Do
            recordvar.EmName = InputBox("职工姓名:")
            recordvar.Wunit = InputBox("所在单位:")
            recordvar.Age = InputBox("职工年龄:")
            recordvar.Salary = InputBox("职工工资:")
            recordnumber += 1
            FilePut(1, recordvar, recordnumber)
            aspect = InputBox("More(Y/N)?")
 Loop Until UCase(aspect) = "N"
End Sub

'执行顺序读文件操作

Sub File_read1()
        Dim i As Long
        Debug.WriteLine("")
        Debug.WriteLine("姓名             单位         " & " 年龄    工资  记录号")
        Debug.WriteLine("")
        For i = 1 To recordnumber
            FileGet(1, recordvar, i)
            Debug.Write(recordvar.EmName)
            Debug.Write("   " & recordvar.Wunit & "   ")
            Debug.Write(Str(recordvar.Age) & "   ")
            Debug.WriteLine(Str(recordvar.Salary) & "   " & Str(Loc(1)))
        Next i
        Debug.WriteLine("")
End SubSub File_read2()
        Dim Getmorerecords As Boolean = True
        Dim recordnum As Integer
        Do
            recordnum = InputBox("请输入要查看的记录号(输入0结束):")
            If recordnum > 0 And recordnum <= recordnumber Then
                FileGet(1, recordvar, recordnum)
                Debug.WriteLine("")
                Debug.WriteLine("姓名             单位         " & "年龄    工资     记录号")
                Debug.WriteLine("")
   Debug.Write(recordvar.EmName)
                Debug.Write("     " & Trim(recordvar.Wunit) & "     ")
                Debug.Write(Str(recordvar.Age) & "     ")
                Debug.WriteLine(Str(recordvar.Salary) & "     " & Str(Loc(1)))
                Debug.WriteLine("")
            ElseIf recordnum = 0 Then
                Getmorerecords = False
            Else
                MsgBox("输入的值超出记录号范围,请重新输入!")
            End If
        Loop While Getmorerecords
End SubPrivate Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
        FileOpen(1, "d:/temp/employee.txt", OpenMode.Random, OpenAccess.ReadWrite, , recLen)
        recordnumber = LOF(1) / recLen
        Dim Newline As String = Chr(13) + Chr(10)
        Dim msg As String
        Dim resp As Integer
        msg = "1.建立文件和增加记录"
        msg = msg + "  2.顺序方式读记录"
        msg = msg + Newline + "3.通过记录号读文件"
        msg = msg + "    4.代换记录"
        msg = msg + Newline + "5.删除记录"
        msg = msg + "            0.退出程序"
        msg = msg + Newline + Newline + "请输入数字选择:"
        msg = msg + Newline
Begin:
        resp = InputBox(msg, "随机文件存取")
        Select Case resp
            Case 0
                FileClose(1)
                End
            Case 1
                File_Write()
            Case 2
                File_read1()
            Case 3
                File_read2()
            Case 4
                'Rec_replace( )
            Case 5
                'Deleterec
        End Select
        GoTo Begin
End Sub

随机文件中记录的增加、代换与删除
⒈ 增加记录:先找到文件最后一个记录的记录号,然后把要增加的记录写到它的后面 。
⒉  代换记录:用FilePut函数可以代换随机文件中已有的记录。

Sub rec_replace()
        Dim rep As Long
        recordvar.EmName = InputBox("职工姓名:")
        recordvar.Wunit = InputBox("所在单位:")
        recordvar.Age = InputBox("职工年龄:")
        recordvar.Salary = InputBox("职工工资:")
        rep = InputBox("请输入需要代换的记录号")
        FilePut(1, recordvar, rep)
End Sub

⒊ 删除记录

Sub deleterec(ByRef position As Integer)
repeat:
        FileGet(1, recordvar, position + 1)
        If Loc(1) = recordnumber Then GoTo finish
        FilePut(1, recordvar, position)
        position = position + 1
        GoTo repeat
finish:
        recordnumber = recordnumber - 1
 End Sub

用控件显示和修改随机文件
编写程序,用控件显示和修改随机文件中的数据。

'定义结构类型
Structure RecordType
        <VBFixedString(10)> Dim EmName As String
        <VBFixedString(16)> Dim Wunit As String
        Dim Age As Short
        Dim Salary As Short
End Structure'定义窗体层变量
Dim recordvar As RecordType
Dim recLen As Integer = Len(recordvar)
Dim position As Integer
Dim recordnumber As LongSub display()
        FileGet(1, recordvar, position)
        TextBox1.Text = recordvar.EmName
        TextBox2.Text = recordvar.Wunit
        TextBox3.Text = recordvar.Age
        TextBox4.Text = recordvar.Salary
 End Sub'打开文件
Private Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
        FileOpen(1, "d:/temp/employee.txt", OpenMode.Random, OpenAccess.ReadWrite, , recLen)
        recordnumber = LOF(1) / Len(recordvar)
        position = 1
        display()
 End Sub'显示前一个记录。
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        If position > 1 Then
            position -= 1
            display()
        ElseIf position = 1 Then
            MsgBox("这是第一个记录", , "")
        End If
 End Sub'显示下一个记录。
Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim msg As String
        Dim resp As Short
        If position < recordnumber Then
            position = position + 1
            display()
        ElseIf position = recordnumber Then
            msg = "这是最后一个记录" + Chr(13) + Chr(10)
            msg = msg + "是否关闭文件?"
            resp = MsgBox(msg, 36, "请选择")
            If resp = 6 Then
                FileClose(1)
                End
            End If
        End If
 End Sub'修改记录。
Private Sub Button4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button4.Click
        recordvar.EmName = TextBox1.Text
        recordvar.Wunit = TextBox2.Text
        recordvar.Age = TextBox3.Text
        recordvar.Salary = TextBox4.Text
        FilePut(1, recordvar, position)
 End Sub'退出程序。
Private Sub Button5_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button5.Click
        End
End Sub

 

二进制文件
二进制文件与随机文件的存取操作类似:⑴ 不需要在读和写之间切换。 ⑵ 读写随机文件的函数FileGet/FilePut也可用于读写二进制文件

编写程序,实现二进制文件的读写操作。

Structure person
        Public ID As Integer
        Public Name As String
End Structure
Dim MyRecord As person
Dim RecordNumber As IntegerPrivate Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Text = "二进制文件存取"
        Button1.Text = "写入数据"
        Button2.Text = "读取数据"
        Button3.Text = "退出程序"
        TextBox1.Text = ""
 End SubPrivate Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim resp As Char
        FileOpen(1, "d:/bfile.txt", OpenMode.Binary)
        Do
            MyRecord.ID = InputBox("请输入编号")
            MyRecord.Name = InputBox("请输入姓名")
            FilePut(1, MyRecord)
            resp = InputBox("继续输入吗?(Y/N)")
        Loop While UCase(resp) = "Y"
        FileClose(1)
 End SubPrivate Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim S As String
        Dim cl As String = Chr(13) & Chr(10)
        FileOpen(1, "d:/bfile.txt", OpenMode.Binary)
        Do While Not EOF(1)
            FileGet(1, MyRecord)
            S = S & MyRecord.ID & " " & MyRecord.Name & cl
        Loop
        TextBox1.Text = S
        FileClose(1)
 End SubPrivate Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
        Close()
 End Sub

 

****流与System.IO模型
⒈ 类
⒉ 结构
WaitChangedResult:含有关于所发生的更改的信息。
⒊ 枚举
⑴ FileAccess:定义用于控制对文件的读访问、写访问或读/写访问的常数。
⑵ FileAttributes:提供文件和目录的属性。
⑶ FileMode:指定操作系统打开文件的方式。
⑷ FileShare:含有用于控制其他FileStream对同一文件可以具有的访问类型的常数。
⑸ NotifyFilters:指定要在文件或文件夹中监视的更改。
⑹ SeekOrigin:指定文件存取时的相对位置。
⑺ WatcherChangeTypes:可能会发生的文件或目录更改。

System.IO名称空间的功能
System.IO名称空间具有如下功能(括号中是提供相应功能的类)。
⑴ 建立、删除以及管理文件和目录(File和Directionary)。
⑵ 监控目录和文件的访问操作(FileSystemWatcher)。
⑶ 对流进行单字节字符或字符块的读写操作(StreamReader和SteamWriter)。
⑷ 对流进行多字节字符(即宽字符)的读写操作(StreamReader和SteamWriter)。
⑸ 对流行进行字符的读写操作(StreamReader和StreamWriter)。
⑹ 对字符串进行字符的读写操作,并允许把字符串作为字符流处理(StringReader和StringWriter)。
⑺ 从一个流中读取数据类型和对象,或者将数据类型和对象写入流中(BinaryReader和BinaryWriter)。
⑻ 文件的随机访问(FileStream)。
⑼ 系统性能优化(MemoryStram和BufferedStream)。
⑽枚举文件或目录的属性(FileAccess、FileMode、FileShare、FileAttributes和SirectoryAttributes)。
⑾ 监控文件或目录可能的改变(WatcherChangeTypes)。
⑿ 枚举文件或目录可能的改变(ChangedFilters)。
⒀ 指定监控的文件或目录(WatcherTarget)。
⒁ 为访问文件指定文件指定的相对位置(SeekOrigin)