精华内容
下载资源
问答
  • VBA操作文件四大方法之二-VBA文件处理语句   二、利用VBA文件处理语句来处理文件 (一)文件处理 1. Name 语句 2、FileCopy 语句 3、Kill 语句 4、GetAttr 函数 5、SetAttr 语句 6、FileLen 函数 7、...

    VBA操作文件四大方法之二-VBA文件处理语句
       
    二、利用VBA文件处理语句来处理文件
    (一)文件处理
    1.   Name 语句
    2、FileCopy 语句
    3、Kill 语句
    4、GetAttr 函数
    5、SetAttr 语句
    6、FileLen 函数
    7、FileDateTime 函数
    (二)目录处理
    1、CurDir 函数
    2、ChDir 语句
    3、ChDrive 语句
    4、Dir 函数
    5、MkDir 语句
    6、RmDir 语句
    (三)处理文本文件
    1、Open 语句
    2、Close 语句
    3、Reset 语句
    4、FreeFile 函数
    5、EOF 函数
    6、LOF 函数
    7、Loc 函数
    8、Input # 语句
    9、Write # 语句
    10、Line Input # 语句
    11、Input 函数
    12、Print # 语句
    13、Width # 语句
    (四)处理二进制文件
    1、Put 语句
    2、Get 语句
    3、Seek 语句
    4、Seek 函数

        VBA包含了许多用于文件操作的语句和函数,可以满足绝大多数情况下的文件操作要求。下面我们按照操作目的进行一一介绍。

    (一)文件处理
    1.    Name 语句
        语法:Name oldpathname As newpathname
        功能:重命名一个文件、目录、或文件夹,移动一个文件。
        说明:在一个已打开的文件上使用 Name,将会产生错误。进行文件操作时,一定要注意错误处理。
        示例:
            On Error Resume Next '错误处理
            Name "f:\TEST.xls" As "f:\TEST123.xls" '重命名
            Name "f:\TEST.xls" As "f:\dll\TEST.xls" '移动文件
            Name "f:\TEST.xls" As "d:\TEST123.xls" '跨驱动器移动并重命名文件
        注意:Name不能移动一个目录或文件夹。

    2、FileCopy 语句
        语法:FileCopy source, destination
        功能:复制一个文件。
        说明:如果对一个已打开的文件使用 FileCopy 语句,则会产生错误。
        示例:
            FileCopy "f:\TEST.xls", "e:\TEST.xls" '从F盘复制TEST.xls到E盘

    3、Kill 语句
        语法:Kill pathname
        功能:从磁盘中删除文件。
        说明:Kill 支持多字符 (*) 和单字符 (?) 的统配符来指定多重文件。如果使用 Kill 来删除一个已打开的文件,则会产生错误。
        示例:
            Kill "f:\TEST.xls" ’删除F盘的TEST.xls文件
            Kill "f:\*.xls" ' 删除F盘所有xls文件

    4、GetAttr 函数
        语法:GetAttr(pathname)
        功能:获取一个文件、目录、或文件夹的属性。返回一个 Integer值。
        返回值
            由 GetAttr 返回的值,是下面这些属性值的总和:
        常数值 描述
            vbNormal 0 常规
            vbReadOnly 1 只读
            vbHidden 2 隐藏
            vbSystem 4 系统文件
            vbDirectory 16 目录或文件夹
            vbArchive 32 存档文件
            vbalias 64 指定的文件名是别名。只在Macintosh中可用。
        说明:若要判断是否设置了某个属性,在 GetAttr 函数与想要得知的属性值之间使用 And 运算符与逐位比较。如果所得的结果不为零,则表示设置了这个属性值。
        示例:
            Debug.Print GetAttr("F:\test.txt") '若为存档文件,在立即窗口可看到值为32
            Debug.Print GetAttr("F:\test.txt") '将属性—高级—可存档文件的勾去掉后,值为0
        为判断一个文件是否只读,可用下法:
            Debug.Print GetAttr("F:\test.txt") And vbReadOnly
        若值非零,说明时只读的。

    5、SetAttr 语句
        语法:SetAttr pathname, attributes
        功能:为一个文件设置属性。
        说明:如果想要给一个已打开的文件设置属性,则会产生运行时错误。
        示例:
            SetAttr"F:\test.txt", vbHidden ' 设置隐藏属性。
            SetAttr"F:\test.txt", vbHidden + vbReadOnly ' 设置隐藏并只读。

    6、FileLen 函数
        语法:FileLen(pathname)
        功能:获取一个文件的长度,单位是字节。
        说明:当调用 FileLen 函数时,不需要打开文件,如果所指定的文件已经打开,则返回的值是这个文件在打开前的大小。

    7、FileDateTime 函数
        语法:FileDateTime(pathname)
        功能:获取一个文件被创建或最后修改后的日期和时间。
        示例:
                Debug.Print FileDateTime("F:\TEST.xls") '在立即窗口可看到2007-3-29 19:28:27
       
    (二)目录处理
    1、CurDir 函数
        语法:CurDir[(drive)]
        功能:返回当前的路径。
        说明:drive 参数是可选的,它指定一个存在的驱动器。如果没有指定驱动器,或 drive 是零长度字符串 (""),则 CurDir 会返回当前驱动器的路径。
        示例:
            Debug.Print CurDir ' 返回“C:\Documents and Settings\yc\My Documents”。
            Debug.Print CurDir("C") ' 返回“C:\Documents and Settings\yc\My Documents”。
            Debug.Print CurDir("D") ' 返回“D:\”。

    2、ChDir 语句
        语法:ChDir path
        功能:改变当前的目录或文件夹。
        说明:ChDir 语句改变缺省目录位置,但不会改变缺省驱动器位置。缺省驱动器一般是C。
        示例:
            ChDir "D:\temp"
            Debug.Print CurDir ' 返回“C:\Documents and Settings\yc\My Documents”。
            Debug.Print CurDir("D") ' 返回“D:\temp”。
        与上例比较,此时D盘的当前目录已经变为“D:\temp”,但是缺省驱动器还是C。

    3、ChDrive 语句
        语法:ChDrive drive
        功能:改变当前的驱动器。
        说明:如果使用零长度的字符串 (""),则当前的驱动器将不会改变。如果 drive 参数中有多个字符,则 ChDrive 只会使用首字母。
        示例:
            ChDrive "D"
            ChDir "D:\temp"
            Debug.Print CurDir ' 返回“D:\temp”。
            Debug.Print CurDir("D") ' 返回“D:\temp”。
        与上例比较,用CurDir返回的是“D:\temp”,当前驱动器已经变为D了。

    4、Dir 函数
        语法:Dir[(pathname[, attributes])]
        两个参数都是可选的,attributes表示文件属性。
        功能:返回一个文件名、目录名或文件夹名称,它必须与指定的模式或文件属性、或磁盘卷标相匹配。
        说明:在第一次调用 Dir 函数时,必须指定 pathname,否则会产生错误。如果也指定了文件属性,那么就必须包括 pathname。
        Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。不必访问到所有匹配当前 pathname 的文件名,就可以改变到一个新的 pathname 上。但是,不能以递归方式来调用 Dir 函数。以 vbDirectory 属性来调用 Dir 不能连续地返回子目录。
        示例:
            Debug.Print Dir("F:\TEST.xls") ’返回"TEST.xls"
            Debug.Print Dir("F:\*.xls") ’返回按条件第一个找到的文件名。
            Debug.Print Dir("F:\*.txt",vbReadOnly) ’返回第一个只读的txt文件
        以下过程可显示C盘根目录下的所有目录.
        Sub DirC()
            MyPath = "c:\"
            MyName = dir(MyPath, vbDirectory) ' 找寻第一项。
            Do While MyName <> "" ' 开始循环。
                   ' 跳过当前的目录及上层目录。
                If MyName <> "." And MyName <> ".." Then
                    ' 使用位比较来确定 MyName 代表一目录。
            I        f (GetAttr(MyPath & MyName) And vbDirectory) = vbDirectory Then
                            Debug.Print MyName ' 如果它是一个目录,将其名称显示出来。
                     End If
                End If
                MyName = dir ' 查找下一个目录。
            Loop
        End Sub
        以下过程利用递归可以查找目录和子目录下的所有文件。
        Public Sub FindFile(mPath As String, Optional sFile As String = "")
            On Error Resume Next
            Dim s As String, sDir() As String
            Dim i As Long, d As Long
            If Right(mPath, 1) <> "\" Then
                    mPath = mPath & "\"
            End If
            '查找目录下的文件
            s = dir(mPath & sFile, vbArchive + vbDirectory + vbHidden + vbNormal + vbReadOnly + vbSystem)
            Do While s <> ""
                Debug.Print mPath & s
                s = dir
            Loop
                '查找目录下的子目录
            s = dir(mPath, vbArchive + vbDirectory + vbHidden + vbNormal + vbReadOnly + vbSystem)
            Do While s <> ""
                If s <> "." And s <> ".." Then
                    If (GetAttr(mPath & s) And vbDirectory) = vbDirectory Then
                        d = d + 1
                        ReDim Preserve sDir(d)
                        sDir(d) = mPath & s
                    End If
                End If
                s = dir
            Loop
            '开始递归
            For i = 1 To d
                FindFile sDir(d) & "\"
            Next
        End Sub
       
    5、MkDir 语句
        语法:MkDir path
        功能:创建一个新的目录或文件夹。
        说明:path 可以包含驱动器。如果没有指定驱动器,则 MkDir 会在当前驱动器上创建新的目录或文件夹。
        示例:
        MkDir "MYDIR" '在当前目录建立新的目录或文件夹。

    6、RmDir 语句
        语法:RmDir path
        功能:删除一个存在的目录或文件夹。
        说明:如果想要使用 RmDir 来删除一个含有文件的目录或文件夹,则会发生错误。在试图删除目录或文件夹之前,先使用 Kill 语句来删除所有文件。
        示例:
            RmDir "MYDIR" ' 将 MYDIR 删除。

    (三)处理文本文件
    1、Open 语句
        语法:Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength]
        其中access、lock、reclength为可选参数,一般不用。
            mode 指定打开文件的方式。有5种:
            Input:以输入方式打开,即读取方式。
           Output:以输出方式打开,即写入方式。
            Append:以追加方式打开,即添加内容到文件末尾。
            Binary:以二进制方式打开。
            Random:以随机方式打开,如果未指定方式,则以 Random 方式打开文件。
            filenumber 是一个有效的文件号,范围在 1 到 511 之间。可以指定,也可使用 FreeFile 函数可得到下一个可用的文件号。
        说明:如果 pathname 指定的文件不存在,那么,在用 Append、Binary、Output、或 Random 方式打开文件时,可以建立这一文件。
        示例:
            Open "F:\TEST.txt" For Input As #1 '以输入方式打开
            Open "F:\TEST.xls" For Binary As #1 '以二进制方式打开

    2、Close 语句
        语法:Close [filenumberlist]
        filenumberlist 参数为一个或多个文件号,若省略 filenumberlist,则将关闭 Open 语句打开的所有活动文件。
        说明:打开文件后,必须在使用完后关闭文件。
        示例:
            Dim I, FileName
            For I = 1 To 3
                FileName = "TEST" & I ' 创建文件名。
                Open FileName For Output As #I ' 打开文件。
                Print #I, "This is a test." ' 将字符串写入文件。
            Next I
            Close ' 将三个已打开的文件全部关闭。

    3、Reset 语句
        语法:Reset
        功能:关闭所有用 Open 语句打开的磁盘文件。
        说明:Reset 语句关闭 Open 语句打开的所有活动文件,并将文件缓冲区的所有内容写入磁盘。
        示例:
            Dim FileNumber
            For FileNumber = 1 To 5
                Open "TEST" & FileNumber For Output As #FileNumber
                Write #FileNumber, "Hello World" ' 将数据写入文件。
            Next FileNumber
            Reset ' 关闭文件并将缓冲区内的数据写到磁盘中。

    4、FreeFile 函数
        语法:FreeFile[(rangenumber)]
        参数 rangenumber指定一个范围,以便返回该范围之内的下一个可用文件号。指定 0(缺省值)则返回一个介于 1 – 255 之间的文件号。指定 1 则返回一个介于 256 – 511 之间的文件号。
        功能:提供一个尚未使用的文件号。
        示例:
            Dim fnum As Integer
            fnum = FreeFile
            Open "F:\TEST.txt" For Input As #fnum
            Close #fnum   

    5、EOF 函数
        语法:EOF(filenumber)
        功能:返回一个 Integer,它包含 Boolean 值 True,表明已经到达为 Random 或顺序 Input 打开的文件的结尾。

    6、LOF 函数
        语法:LOF(filenumber)
        功能:返回一个 Long,表示用 Open 语句打开的文件的大小,该大小以字节为单位。

    7、Loc 函数
        语法:LOc(filenumber)
        功能:返回一个 Long,在已打开的文件中指定当前读/写位置。
      
    8、Input # 语句
        语法:Input #filenumber, varlist
        功能:从已打开的顺序文件中读出数据并将数据指定给变量。
        说明:通常用 Write # 将 Input # 语句读出的数据写入文件。为了能够用 Input # 语句将文件的数据正确读入到变量中,在将数据写入文件时,要使用 Write # 语句而不使用 Print # 语句。使用 Write # 语句可以确保将各个单独的数据域正确分隔开。
        示例:
        本示例使用 Input # 语句将文件内的数据读入两个变量中。本示例假设 TESTFILE文件内含数行以 Write # 语句写入的数据;也就是说,每一行数据中的字符串部分都是用双引号括起来,而与数字用逗号隔开,例如,("Hello", 234)。
        Dim MyString, MyNumber
        Open "TESTFILE" For Input As #1 ' 打开输入文件。
        Do While Not EOF(1) ' 循环至文件尾。
            Input #1, MyString, MyNumber ' 将数据读入两个变量。
            Debug.Print MyString, MyNumber ' 在立即窗口中显示数据。
        Loop
        Close #1 ' 关闭文件。

    9、Write # 语句
        语法:Write #filenumber, [outputlist]
        功能:将数据写入顺序文件。
        说明:通常用 Input # 从文件读出 Write # 写入的数据。
        如果省略 outputlist,并在 filenumber 之后加上一个逗号,则会将一个空白行打印到文件中。多个表达式之间可用空白、分号或逗号隔开。空白和分号等效。
        用 Write # 将数据写入文件时将遵循几个通用的约定,使得无论什么区域都可用 Input # 读出并正确解释数据:
        ·在写入数值数据时总使用句号作为十进制分隔符。
        ·对于 Boolean 类型的数据,或者打印 #TRUE# 或者打印 #FALSE#。无论在什么地区,都不将 True 和 False 这两个关键字翻译出来。
        ·使用通用的日期格式将 Date 类型的数据写入文件中。当日期或时间的部件丢失或为零时,只将现有部分写入文件中。
        ·如果 outputlist 的数据为 Empty,则不将任何数据写入文件。但对 Null 数据,则要写入 #NULL#。
        ·如果 outputlist 数据为 Null 数据,则将 #NULL# 写入文件中。
        ·对于 Error 类型的数据,输出看起来与 #ERROR errorcode# 一样。无论在什么地区,都不将关键字 Error 翻译出来。
        与 Print # 语句不同,当要将数据写入文件时,Write # 语句会在项目和用来标记字符串的引号之间插入逗号。没有必要在列表中键入明确的分界符。Write # 语句在将 outputlist 中的最后一个字符写入文件后会插入一个新行字符,即回车换行符,(Chr(13) + Chr(10))。
        示例:
            Open "F:\test.txt" For Output As #1 ' 打开输出文件。
            Write #1, "Hello World", 1234 ' 写入以逗号隔开的数据。
            Write #1, ' 写入空白行。
            Dim MyBool, MyDate, MyNull, MyError
                ' 赋值 Boolean、Date、Null 及 Error 等。
            MyBool = False : MyDate = #February 12, 1969# : MyNull = Null
            MyError = CVErr(32767)
                ' Boolean 数据以 #TRUE# 或 #FALSE# 的格式写入。
            ' 日期以通用日期格式写入,例如:#1994-07-13# 代表
                    ' 1994 年 1 月 13 日。Null 数据以 #NULL# 格式写入。
            ' Error 数据以 #ERROR 错误代号# 的格式写入。
            Write #1, MyBool; " is a Boolean value"
            Write #1, MyDate; " is a date"
            Write #1, MyNull; " is a null value"
            Write #1, MyError; " is an error value"
            Close #1 ' 关闭文件。
            我们可以看到写入的内容为:
            "Hello World",1234
            #FALSE#," is a Boolean value"
            #1969-02-12#," is a date"
            #NULL#," is a null value"
            #ERROR 32767#," is an error value"

    10、Line Input # 语句
        语法:Line Input #filenumber, varname
        功能:从已打开的顺序文件中读出一行并将它分配给 String 变量。
        说明:通常用 Print # 与 Line Input # 语句配合使用。
        Line Input # 语句一次只从文件中读出一个字符,直到遇到回车符 (Chr(13)) 或回车–换行符 (Chr(13) + Chr(10)) 为止。回车–换行符将被跳过,而不会被附加到字符串上。
        示例:
            Dim TextLine
            Open "TESTFILE" For Input As #1 ' 打开文件。
            Do While Not EOF(1) ' 循环至文件尾。
                Line Input #1, TextLine ' 读入一行数据并将其赋予某变量。
                Debug.Print TextLine ' 在立即窗口中显示数据。
            Loop
            Close #1 ' 关闭文件。

    11、Input 函数
        语法:Input(number, [#]filenumber)
        其中number 指定要返回的字符个数。
        功能:返回 String,它包含以 Input 或 Binary 方式打开的文件中的字符。
        说明:通常用 Print # 或 Put 将 Input 函数读出的数据写入文件。Input 函数只用于以 Input 或 Binary 方式打开的文件。
        与 Input # 语句不同,Input 函数返回它所读出的所有字符,包括逗号、回车符、空白列、换行符、引号和前导空格等。
        示例:
            Dim MyChar
            Open "f:\test.txt" For Input As #1
            Do While Not EOF(1) ' 循环至文件尾。
                MyChar = Input(1, #1) ' 读入一个字符。
                Debug.Print MyChar ' 显示到立即窗口。
            Loop
            Close #1
        下面这个函数可以将文本文件的数据一次读入到一个字符串(但是若包含中文时会出错,因为一个中文字占2个字节)。
        Public Function ReadText(FileName As String)
            Dim fnum%, isopen As Boolean
            On Error GoTo erro
            fnum = FreeFile()
            Open FileName For Input As #fnum
            isopen = True
            ReadText = Input(LOF(fnum), fnum)
            erro:
            If isopen Then Close #fnum
            If err Then Debug.Print err.Number, err.Description
        End Function

    12、Print # 语句
        语法:Print #filenumber, [outputlist]
        outputlist 参数的设置如下:
        [{Spc(n) | Tab[(n)]}] [expression] [charpos]
        Spc(n) 用来在输出数据中插入空白字符,而 n 指的是要插入的空白字符数。
        Tab(n) 用来将插入点定位在某一绝对列号上,这里,n 是列号。使用无参数的 Tab 将插入点定位在下一个打印区的起始位置。
        expression 要打印的数值表达式或字符串表达式。
        charpos 指定下一个字符的插入点。使用分号将插入点定位在上一个显示字符之后。用 Tab(n) 将插入点定位在某一绝对的列号上,用无参数的 Tab 将插入点定位在下一个打印区的起始处。如果省略 charpos,则在下一行打印下一个字符。
       
        功能:将格式化显示的数据写入顺序文件中。
        说明:通常用 Line Input # 或 Input 读出 Print # 在文件中写入的数据。
        示例:
            Open "F:\test.txt" For Output As #1 ' 打开输出文件。
            Print #1, "This is a test" ' 将文本数据写入文件。
            Print #1, ' 将空白行写入文件。
            Print #1, "Zone 1"; Tab; "Zone 2" ' 数据写入两个区(print zones)。
            Print #1, "Hello"; " "; "World" ' 以空格隔开两个字符串。
            Print #1, Spc(5); "5 leading spaces " ' 在字符串之前写入五个空格。
            Print #1, Tab(10); "Hello" ' 将数据写在第十列。
            ' 赋值 Boolean、Date、Null 及 Error 等。
            Dim MyBool, MyDate, MyNull, MyError
            MyBool = False: MyDate = #2/12/1969#: MyNull = Null
            MyError = CVErr(32767)
            ' True、False、Null 及 Error 会根据系统的地区设置自动转换格式。
            ' 日期将以标准的短式日期的格式显示。
            Print #1, MyBool; " is a Boolean value"
            Print #1, MyDate; " is a date"
            Print #1, MyNull; " is a null value"
            Print #1, MyError; " is an error value"
            Close #1
        以上代码写入的内容如下:
            This is a test
            Zone 1 Zone 2
            Hello World
            5 leading spaces
            Hello
            False is a Boolean value
            1969-2-12 is a date
            Null is a null value
            Error 32767 is an error value

    13、Width # 语句
        语法:Width #filenumber, width
        width 必要。范围在 0–255 之间的数值表达式,在新的一行开始之前,指出在该行上可出现多少字符。如果 width 等于 0,则行的长度不受限制。width 的缺省值为 0。
        功能:将一个输出行的宽度指定给用 Open 语句打开的文件。
        示例:
            Dim I
            Open "f:\TESTFILE.txt" For Output As #1
            Width #1, 5 ' 设置输出行宽为 5。
            For I = 0 To 9 ' 循环 10 次。
                Print #1, Chr(48 + I); ' 每行输出五个字符。
            Next I
            Close #1
        以上代码写入的内容如下:
        01234
        56789


    (四)处理二进制文件
        打开二进制文件可以使用Open语句的Random和Binary方式打开。二进制文件读写使用Get和Put语句。
    1、Put 语句
        语法:Put [#]filenumber, [recnumber], varname
        recnumber 可选。Variant (Long)。记录号(Random 方式的文件)或字节数(Binary 方式的文件),指明在此处开始写入。
        说明:通常用 Get 将 Put 写入的文件数据读出来。
        示例:
            Dim num As Long, text As String
            num = 12345
            text = "a string"
            Open "f:\data.bin" For Binary As #1 '打开或创建一个二进制文件
            Put #1, , num '写入4个字节
            Put #1, , text '写入8个字节(字符串长为8)
            Close #1

    2、Get 语句
        语法:Get [#]filenumber, [recnumber], varname
        recnumber 可选。Variant (Long)。记录号(Random 方式的文件)或字节数(Binary 方式的文件),以表示在此处开始读出数据。
        功能:将一个已打开的磁盘文件读入一个变量之中。
        说明:通常用 Put 将 Get 读出的数据写入一个文件。
        示例:读取以上代码写入的内容
            Dim num As Long, text As String
            Open "f:\data.bin" For Binary As #1
            Get #1, , num
            text = Space$(8) '准备8个字节的字符串
            Get #1, , text '读入
            Debug.Print num, text
            Close #1
        在立即窗口可以看到如下内容:
            12345 a string

    3、Seek 语句
        语法:Seek [#]filenumber, position
        其中position 为介于 1~ 2,147,483,647(相当于 2^31 – 1)之间的数字,指出下一个读写操作将要发生的位置。
        功能:在 Open 语句打开的文件中,设置下一个读/写操作的位置。
        说明:可以用Seek语句指定Get语句的读取位置,但在 Get 及 Put 语句中指定的记录号将覆盖由 Seek 语句指定的文件位置。
        示例:
            Dim MaxSize, NextChar, MyChar
            Open "TESTFILE" For Input As #1
            MaxSize = LOF(1) ' 取得文件的总字符数。
            ' 用循环读入所有记录,但是从最后的记录开始往前读。
            For NextChar = MaxSize To 1 Step -1
                Seek #1, NextChar ' 设置读写位置。
                MyChar = Input(1, #1) ' 读入一字符。
            Next NextChar
            Close #1

     4、Seek 函数
        语法:Seek(filenumber)
        功能:返回一个 Long,在 Open 语句打开的文件中指定当前的读/写位置。
        说明:在使用Get语句读取文件时,必须用LOF函数来判断是否到达文件末尾,而不是用EOF函数。可以使用Seek函数判断当前位置,然后与LOF的值比较。
        示例:
        Do While Seek(1) < LOF(1)
            '继续读取    ......
        Loop
       
    (五)总结
        VBA语句的文件操作涵盖了文件操作的绝大部分内容,很多函数的使用也很简单,一般的文件读写也非常方便,特别是对文本文件。但对于复杂的文件读写,代码 的结构和维护性都不好。因此在VB6之后,微软引入了FileSystemObject对象模型,提供了面向对象的类库,来操作驱动器、文件夹和文件。但 对于二进制文件的操作,目前还只能用VBA语句。
        Excel文件本身就是二进制文件,它使用的文件格式叫做BIFF(Binary Interchange File Format),即二进制可交换文件格式(但2007开始使用OOXML格式)。关于其内部的结构,本人也在研究中。以二进制结构打开Excel文件,不 但可以读取其表格中的数据,还可以读取其所有的信息(包括密码)。注意,以Open语句打开文件,并不是我们通常的双击一个文件打开显示到屏幕上,而是将 其存放在磁盘上的数据读入到缓冲区,不是可视化的打开。这种打开是不需要密码的,即使你的Excel文件设置了打开密码,还是照打开不误,这也正是 Excel文件不安全的根源所在。我以前发过一篇关于破解的文章,里面破解VBA工程密码的方法就是用二进制替换。由于论坛不让讨论破解的话题,这里就不 再详细分析代码了,感兴趣的请自行研究。当然,Excel的其他密码也是可类似破解的,前提是你必须十分了解Excel的内部结构,知道密码放在哪里,才 能替换。知道的解密的方法,自然可以针对性的改进加密的方法。好了,这里就不再罗嗦了,如果对Excel的内部结构感兴趣,可以先看这篇文章,看懂再说。

    展开全文
  • 利用VBA文件处理语句来处理文件

    千次阅读 2009-01-15 16:47:00
    VBA包含了许多用于文件操作的语句和函数,可以满足绝大多数情况下的文件操作要求。下面我们按照操作目的进行一一介绍。(一)文件处理 1.Name 语句语法:Name oldpathname As newpathname功能:重命名一个文件、...

         VBA包含了许多用于文件操作的语句和函数,可以满足绝大多数情况下的文件操作要求。下面我们按照操作目的进行一一介绍。

    (一)文件处理
        
    1.Name 语句

    语法:Name oldpathname As newpathname

    功能:重命名一个文件、目录、或文件夹,移动一个文件。

    说明:在一个已打开的文件上使用 Name,将会产生错误。进行文件操作时,一定要注意错误处理。

    示例:
    On Error Resume Next     '错误处理
    Name "f:/TEST.xls" As "f:/TEST123.xls"   '重命名
    Name "f:/TEST.xls" As "f:/dll/TEST.xls"   '移动文件
    Name "f:/TEST.xls" As "d:/TEST123.xls"   '跨驱动器移动并重命名文件

    注意:Name不能移动一个目录或文件夹。

    2、FileCopy 语句

    语法:FileCopy source, destination

    功能:复制一个文件。

    说明:如果对一个已打开的文件使用 FileCopy 语句,则会产生错误。

    示例:
    FileCopy "f:/TEST.xls", "e:/TEST.xls"   '从F盘复制TEST.xls到E盘

    3、Kill 语句

    语法:Kill pathname

    功能:从磁盘中删除文件。

    说明:Kill 支持多字符 (*) 和单字符 (?) 的统配符来指定多重文件。如果使用 Kill 来删除一个已打开的文件,则会产生错误。

    示例:
    Kill "f:/TEST.xls"   ’删除F盘的TEST.xls文件
    Kill "f:/*.xls"    ' 删除F盘所有xls文件

    4、GetAttr 函数

    语法:GetAttr(pathname)

    功能:获取一个文件、目录、或文件夹的属性。返回一个 Integer值。

    返回值

    由 GetAttr 返回的值,是下面这些属性值的总和:

    常数     值    描述
    vbNormal    0    常规
    vbReadOnly    1    只读
    vbHidden    2    隐藏
    vbSystem    4   系统文件
    vbDirectory    16    目录或文件夹
    vbArchive    32    存档文件
    vbalias    64    指定的文件名是别名。只在Macintosh中可用。

    说明:若要判断是否设置了某个属性,在 GetAttr 函数与想要得知的属性值之间使用 And 运算符与逐位比较。如果所得的结果不为零,则表示设置了这个属性值。

    示例:
    Debug.Print GetAttr("F:/test.txt") '若为存档文件,在立即窗口可看到值为32
    Debug.Print GetAttr("F:/test.txt") '将属性—高级—可存档文件的勾去掉后,值为0

    为判断一个文件是否只读,可用下法:
    Debug.Print GetAttr("F:/test.txt") And vbReadOnly
    若值非零,说明时只读的。

    5、SetAttr 语句

    语法:SetAttr pathname, attributes

    功能:为一个文件设置属性。

    说明:如果想要给一个已打开的文件设置属性,则会产生运行时错误。

    示例:
    SetAttr"F:/test.txt", vbHidden        ' 设置隐藏属性。
    SetAttr"F:/test.txt", vbHidden + vbReadOnly       ' 设置隐藏并只读。

    6、FileLen 函数

    语法:FileLen(pathname)

    功能:获取一个文件的长度,单位是字节。

    说明:当调用 FileLen 函数时,不需要打开文件,如果所指定的文件已经打开,则返回的值是这个文件在打开前的大小。

    7、FileDateTime 函数

    语法:FileDateTime(pathname)

    功能:获取一个文件被创建或最后修改后的日期和时间。

    示例:
    Debug.Print FileDateTime("F:/TEST.xls")   '在立即窗口可看到2007-3-29 19:28:27


    (二)目录处理

    1、CurDir 函数

    语法:CurDir[(drive)]

    功能:返回当前的路径。

    说明:drive 参数是可选的,它指定一个存在的驱动器。如果没有指定驱动器,或 drive 是零长度字符串 (""),则 CurDir 会返回当前驱动器的路径。

    示例:
    Debug.Print CurDir       ' 返回“C:/Documents and Settings/yc/My Documents”。
    Debug.Print CurDir("C")      ' 返回“C:/Documents and Settings/yc/My Documents”。
    Debug.Print CurDir("D")      ' 返回“D:/”。

    2、ChDir 语句

    语法:ChDir path

    功能:改变当前的目录或文件夹。

    说明:ChDir 语句改变缺省目录位置,但不会改变缺省驱动器位置。缺省驱动器一般是C。

    示例:

    ChDir "D:/temp"
    Debug.Print CurDir       ' 返回“C:/Documents and Settings/yc/My Documents”。
    Debug.Print CurDir("D")      ' 返回“D:/temp”。
    与上例比较,此时D盘的当前目录已经变为“D:/temp”,但是缺省驱动器还是C。

    3、ChDrive 语句

    语法:ChDrive drive

    功能:改变当前的驱动器。

    说明:如果使用零长度的字符串 (""),则当前的驱动器将不会改变。如果 drive 参数中有多个字符,则 ChDrive 只会使用首字母。

    示例:
    ChDrive "D"
    ChDir "D:/temp"
    Debug.Print CurDir       ' 返回“D:/temp”。
    Debug.Print CurDir("D")      ' 返回“D:/temp”。

    与上例比较,用CurDir返回的是“D:/temp”,当前驱动器已经变为D了。

    4、Dir 函数

    语法:Dir[(pathname[, attributes])]
           两个参数都是可选的,attributes表示文件属性。
    功能:返回一个文件名、目录名或文件夹名称,它必须与指定的模式或文件属性、或磁盘卷标相匹配。

    说明:在第一次调用 Dir 函数时,必须指定 pathname,否则会产生错误。如果也指定了文件属性,那么就必须包括 pathname。

    Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。不必访问到所有匹配当前 pathname 的文件名,就可以改变到一个新的 pathname 上。但是,不能以递归方式来调用 Dir 函数。以 vbDirectory 属性来调用 Dir 不能连续地返回子目录。

    示例:
    Debug.Print Dir("F:/TEST.xls")   ’返回"TEST.xls"
    Debug.Print Dir("F:/*.xls")   ’返回按条件第一个找到的文件名。
    Debug.Print Dir("F:/*.txt",vbReadOnly) ’返回第一个只读的txt文件

    以下过程可显示C盘根目录下的所有目录.
    Sub DirC()

    MyPath = "c:/"   
    MyName = dir(MyPath, vbDirectory)      ' 找寻第一项。
    Do While MyName <> ""       ' 开始循环。
         ' 跳过当前的目录及上层目录。
         If MyName <> "." And MyName <> ".." Then
             ' 使用位比较来确定 MyName 代表一目录。
             If (GetAttr(MyPath & MyName) And vbDirectory) = vbDirectory Then
                 Debug.Print MyName      ' 如果它是一个目录,将其名称显示出来。
             End If
         End If
         MyName = dir     ' 查找下一个目录。
    Loop

    End Sub

    以下过程利用递归可以查找目录和子目录下的所有文件。

    Public Sub FindFile(mPath As String, Optional sFile As String = "")
    On Error Resume Next
    Dim s As String, sDir() As String
    Dim i As Long, d As Long

    If Right(mPath, 1) <> "/" Then
         mPath = mPath & "/"
    End If
    '查找目录下的文件
    s = dir(mPath & sFile, vbArchive + vbDirectory + vbHidden + vbNormal + vbReadOnly + vbSystem)
    Do While s <> ""
        Debug.Print mPath & s
        s = dir
    Loop
    '查找目录下的子目录
    s = dir(mPath, vbArchive + vbDirectory + vbHidden + vbNormal + vbReadOnly + vbSystem)
    Do While s <> ""
         If s <> "." And s <> ".." Then
             If (GetAttr(mPath & s) And vbDirectory) = vbDirectory Then
             d = d + 1
             ReDim Preserve sDir(d)
             sDir(d) = mPath & s
             End If
         End If
         s = dir
    Loop

    '开始递归        
    For i = 1 To d
         FindFile sDir(d) & "/"
    Next

    End Sub


    5、MkDir 语句

    语法:MkDir path

    功能:创建一个新的目录或文件夹。

    说明:path 可以包含驱动器。如果没有指定驱动器,则 MkDir 会在当前驱动器上创建新的目录或文件夹。

    示例:
    MkDir "MYDIR"     '在当前目录建立新的目录或文件夹。

    6、RmDir 语句

    语法:RmDir path

    功能:删除一个存在的目录或文件夹。

    说明:如果想要使用 RmDir 来删除一个含有文件的目录或文件夹,则会发生错误。在试图删除目录或文件夹之前,先使用 Kill 语句来删除所有文件。

    示例:
    RmDir "MYDIR"       ' 将 MYDIR 删除。


    (三)处理文本文件

    1、Open 语句

    语法:Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength]

    其中access、lock、reclength为可选参数,一般不用。
    mode 指定打开文件的方式。有5种:
    Input:以输入方式打开,即读取方式。
    Output:以输出方式打开,即写入方式。
    Append:以追加方式打开,即添加内容到文件末尾。
    Binary:以二进制方式打开。
    Random:以随机方式打开,如果未指定方式,则以 Random 方式打开文件。

    filenumber   是一个有效的文件号,范围在 1 到 511 之间。可以指定,也可使用 FreeFile 函数可得到下一个可用的文件号。

    说明:如果 pathname 指定的文件不存在,那么,在用 Append、Binary、Output、或 Random 方式打开文件时,可以建立这一文件。

    示例:
    Open "F:/TEST.txt" For Input As #1   '以输入方式打开
    Open "F:/TEST.xls" For Binary As #1   '以二进制方式打开

    2、Close 语句

    语法:Close [filenumberlist]
          filenumberlist 参数为一个或多个文件号,若省略 filenumberlist,则将关闭 Open 语句打开的所有活动文件。

    说明:打开文件后,必须在使用完后关闭文件。

    示例:
    Dim I, FileName
    For I = 1 To 3    
         FileName = "TEST" & I     ' 创建文件名。
         Open FileName For Output As #I     ' 打开文件。
         Print #I, "This is a test."     ' 将字符串写入文件。
    Next I
    Close     ' 将三个已打开的文件全部关闭。

    3、Reset 语句

    语法:Reset

    功能:关闭所有用 Open 语句打开的磁盘文件。

    说明:Reset 语句关闭 Open 语句打开的所有活动文件,并将文件缓冲区的所有内容写入磁盘。

    示例:
    Dim FileNumber
    For FileNumber = 1 To 5    
         Open "TEST" & FileNumber For Output As #FileNumber
         Write #FileNumber, "Hello World"     ' 将数据写入文件。
    Next FileNumber
    Reset     ' 关闭文件并将缓冲区内的数据写到磁盘中。

    4、FreeFile 函数

    语法:FreeFile[(rangenumber)]
           参数 rangenumber指定一个范围,以便返回该范围之内的下一个可用文件号。指定 0(缺省值)则返回一个介于 1 – 255 之间的文件号。指定 1 则返回一个介于 256 – 511 之间的文件号。

    功能:提供一个尚未使用的文件号。

    示例:
    Dim fnum As Integer

    fnum = FreeFile

    Open "F:/TEST.txt" For Input As #fnum

    Close #fnum


    5、EOF 函数

    语法:EOF(filenumber)

    功能:返回一个 Integer,它包含 Boolean 值 True,表明已经到达为 Random 或顺序 Input 打开的文件的结尾。

    6、LOF 函数

    语法:LOF(filenumber)

    功能:返回一个 Long,表示用 Open 语句打开的文件的大小,该大小以字节为单位。

    7、Loc 函数

    语法:LOc(filenumber)

    功能:返回一个 Long,在已打开的文件中指定当前读/写位置。


    8、Input # 语句

    语法:Input #filenumber, varlist

    功能:从已打开的顺序文件中读出数据并将数据指定给变量。

    说明:通常用 Write # 将 Input # 语句读出的数据写入文件。为了能够用 Input # 语句将文件的数据正确读入到变量中,在将数据写入文件时,要使用 Write # 语句而不使用 Print # 语句。使用 Write # 语句可以确保将各个单独的数据域正确分隔开。

    示例:
    本示例使用 Input # 语句将文件内的数据读入两个变量中。本示例假设 TESTFILE文件内含数行以 Write # 语句写入的数据;也就是说,每一行数据中的字符串部分都是用双引号括起来,而与数字用逗号隔开,例如,("Hello", 234)。

    Dim MyString, MyNumber
    Open "TESTFILE" For Input As #1       ' 打开输入文件。
    Do While Not EOF(1)        ' 循环至文件尾。
         Input #1, MyString, MyNumber       ' 将数据读入两个变量。
         Debug.Print MyString, MyNumber       ' 在立即窗口中显示数据。
    Loop
    Close #1          ' 关闭文件。

    9、Write # 语句

    语法:Write #filenumber, [outputlist]

    功能:将数据写入顺序文件。

    说明:通常用 Input # 从文件读出 Write # 写入的数据。
    如果省略 outputlist,并在 filenumber 之后加上一个逗号,则会将一个空白行打印到文件中。多个表达式之间可用空白、分号或逗号隔开。空白和分号等效。

    用 Write # 将数据写入文件时将遵循几个通用的约定,使得无论什么区域都可用 Input # 读出并正确解释数据:

    ·在写入数值数据时总使用句号作为十进制分隔符。

    ·对于 Boolean 类型的数据,或者打印 #TRUE# 或者打印 #FALSE#。无论在什么地区,都不将 True 和 False 这两个关键字翻译出来。

    ·使用通用的日期格式将 Date 类型的数据写入文件中。当日期或时间的部件丢失或为零时,只将现有部分写入文件中。

    ·如果 outputlist 的数据为 Empty,则不将任何数据写入文件。但对 Null 数据,则要写入 #NULL#。

    ·如果 outputlist 数据为 Null 数据,则将 #NULL# 写入文件中。

    ·对于 Error 类型的数据,输出看起来与 #ERROR errorcode# 一样。无论在什么地区,都不将关键字 Error 翻译出来。
    与 Print # 语句不同,当要将数据写入文件时,Write # 语句会在项目和用来标记字符串的引号之间插入逗号。没有必要在列表中键入明确的分界符。Write # 语句在将 outputlist 中的最后一个字符写入文件后会插入一个新行字符,即回车换行符,(Chr(13) + Chr(10))。

    示例:
    Open "F:/test.txt" For Output As #1       ' 打开输出文件。
    Write #1, "Hello World", 1234       ' 写入以逗号隔开的数据。
    Write #1,          ' 写入空白行。

    Dim MyBool, MyDate, MyNull, MyError
    ' 赋值 Boolean、Date、Null 及 Error 等。
    MyBool = False : MyDate = #February 12, 1969# : MyNull = Null
    MyError = CVErr(32767)
    ' Boolean 数据以 #TRUE# 或 #FALSE# 的格式写入。
    ' 日期以通用日期格式写入,例如:#1994-07-13# 代表
    ' 1994 年 1 月 13 日。Null 数据以 #NULL# 格式写入。
    ' Error 数据以 #ERROR 错误代号# 的格式写入。
    Write #1, MyBool; " is a Boolean value"
    Write #1, MyDate; " is a date"
    Write #1, MyNull; " is a null value"
    Write #1, MyError; " is an error value"
    Close #1     ' 关闭文件。

    我们可以看到写入的内容为:
    "Hello World",1234

    #FALSE#," is a Boolean value"
    #1969-02-12#," is a date"
    #NULL#," is a null value"
    #ERROR 32767#," is an error value"

    10、Line Input # 语句

    语法:Line Input #filenumber, varname

    功能:从已打开的顺序文件中读出一行并将它分配给 String 变量。

    说明:通常用 Print # 与 Line Input # 语句配合使用。
    Line Input # 语句一次只从文件中读出一个字符,直到遇到回车符 (Chr(13)) 或回车–换行符 (Chr(13) + Chr(10)) 为止。回车–换行符将被跳过,而不会被附加到字符串上。

    示例:
    Dim TextLine
    Open "TESTFILE" For Input As #1      ' 打开文件。
    Do While Not EOF(1)        ' 循环至文件尾。
         Line Input #1, TextLine       ' 读入一行数据并将其赋予某变量。
         Debug.Print TextLine       ' 在立即窗口中显示数据。
    Loop
    Close #1         ' 关闭文件。

    11、Input 函数

    语法:Input(number, [#]filenumber)
    其中number 指定要返回的字符个数。

    功能:返回 String,它包含以 Input 或 Binary 方式打开的文件中的字符。

    说明:通常用 Print # 或 Put 将 Input 函数读出的数据写入文件。Input 函数只用于以 Input 或 Binary 方式打开的文件。
    与 Input # 语句不同,Input 函数返回它所读出的所有字符,包括逗号、回车符、空白列、换行符、引号和前导空格等。

    示例:
    Dim MyChar
    Open "f:/test.txt" For Input As #1
    Do While Not EOF(1)        ' 循环至文件尾。
         MyChar = Input(1, #1)       ' 读入一个字符。
         Debug.Print MyChar       ' 显示到立即窗口。
    Loop
    Close #1

    下面这个函数可以将文本文件的数据一次读入到一个字符串(但是若包含中文时会出错,因为一个中文字占2个字节)。

    Public Function ReadText(FileName As String)

    Dim fnum%, isopen As Boolean
    On Error GoTo erro
    fnum = FreeFile()
    Open FileName For Input As #fnum
    isopen = True
    ReadText = Input(LOF(fnum), fnum)

    erro:
         If isopen Then Close #fnum
         If err Then Debug.Print err.Number, err.Description

    End Function

    12、Print # 语句

    语法:Print #filenumber, [outputlist]

    outputlist 参数的设置如下:
    [{Spc(n) | Tab[(n)]}] [expression] [charpos]

    Spc(n) 用来在输出数据中插入空白字符,而 n 指的是要插入的空白字符数。
    Tab(n) 用来将插入点定位在某一绝对列号上,这里,n 是列号。使用无参数的 Tab 将插入点定位在下一个打印区的起始位置。
    expression 要打印的数值表达式或字符串表达式。
    charpos 指定下一个字符的插入点。使用分号将插入点定位在上一个显示字符之后。用 Tab(n) 将插入点定位在某一绝对的列号上,用无参数的 Tab 将插入点定位在下一个打印区的起始处。如果省略 charpos,则在下一行打印下一个字符。


    功能:将格式化显示的数据写入顺序文件中。

    说明:通常用 Line Input # 或 Input 读出 Print # 在文件中写入的数据。

    示例:
    Open "F:/test.txt" For Output As #1          ' 打开输出文件。
    Print #1, "This is a test"                   ' 将文本数据写入文件。
    Print #1,                                    ' 将空白行写入文件。
    Print #1, "Zone 1"; Tab; "Zone 2"            ' 数据写入两个区(print zones)。
    Print #1, "Hello"; " "; "World"              ' 以空格隔开两个字符串。
    Print #1, Spc(5); "5 leading spaces "        ' 在字符串之前写入五个空格。
    Print #1, Tab(10); "Hello"                   ' 将数据写在第十列。

    ' 赋值 Boolean、Date、Null 及 Error 等。
    Dim MyBool, MyDate, MyNull, MyError
    MyBool = False: MyDate = #2/12/1969#: MyNull = Null
    MyError = CVErr(32767)
    ' True、False、Null 及 Error 会根据系统的地区设置自动转换格式。
    ' 日期将以标准的短式日期的格式显示。
    Print #1, MyBool; " is a Boolean value"
    Print #1, MyDate; " is a date"
    Print #1, MyNull; " is a null value"
    Print #1, MyError; " is an error value"
    Close #1

    以上代码写入的内容如下:
    This is a test

    Zone 1         Zone 2
    Hello World
          5 leading spaces
              Hello
    False is a Boolean value
    1969-2-12   is a date
    Null is a null value
    Error 32767 is an error value

    13、Width # 语句

    语法:Width #filenumber, width
    width 必要。范围在 0–255 之间的数值表达式,在新的一行开始之前,指出在该行上可出现多少字符。如果 width 等于 0,则行的长度不受限制。width 的缺省值为 0。

    功能:将一个输出行的宽度指定给用 Open 语句打开的文件。

    示例:
    Dim I
    Open "f:/TESTFILE.txt" For Output As #1
    Width #1, 5                                  ' 设置输出行宽为 5。
    For I = 0 To 9                               ' 循环 10 次。
         Print #1, Chr(48 + I);                   ' 每行输出五个字符。
    Next I
    Close #1

    以上代码写入的内容如下:
    01234
    56789


    (四)处理二进制文件
    打开二进制文件可以使用Open语句的Random和Binary方式打开。二进制文件读写使用Get和Put语句。

    1、Put 语句

    语法:Put [#]filenumber, [recnumber], varname

    recnumber 可选。Variant (Long)。记录号(Random 方式的文件)或字节数(Binary 方式的文件),指明在此处开始写入。

    说明:通常用 Get 将 Put 写入的文件数据读出来。

    示例:
    Dim num As Long, text As String
    num = 12345
    text = "a string"
    Open "f:/data.bin" For Binary As #1      '打开或创建一个二进制文件
    Put #1, , num                            '写入4个字节
    Put #1, , text                           '写入8个字节(字符串长为8)
    Close #1


    2、Get 语句

    语法:Get [#]filenumber, [recnumber], varname

    recnumber 可选。Variant (Long)。记录号(Random 方式的文件)或字节数(Binary 方式的文件),以表示在此处开始读出数据。

    功能:将一个已打开的磁盘文件读入一个变量之中。

    说明:通常用 Put 将 Get 读出的数据写入一个文件。

    示例:读取以上代码写入的内容
    Dim num As Long, text As String
    Open "f:/data.bin" For Binary As #1
    Get #1, , num
    text = Space$(8)                         '准备8个字节的字符串
    Get #1, , text                           '读入
    Debug.Print num, text
    Close #1

    在立即窗口可以看到如下内容:
    12345        a string


    3、Seek 语句

    语法:Seek [#]filenumber, position
    其中position 为介于 1~ 2,147,483,647(相当于 2^31 – 1)之间的数字,指出下一个读写操作将要发生的位置。

    功能:在 Open 语句打开的文件中,设置下一个读/写操作的位置。

    说明:可以用Seek语句指定Get语句的读取位置,但在 Get 及 Put 语句中指定的记录号将覆盖由 Seek 语句指定的文件位置。

    示例:
    Dim MaxSize, NextChar, MyChar
    Open "TESTFILE" For Input As #1     
    MaxSize = LOF(1)        ' 取得文件的总字符数。
    ' 用循环读入所有记录,但是从最后的记录开始往前读。
    For NextChar = MaxSize To 1 Step -1    
         Seek #1, NextChar       ' 设置读写位置。
         MyChar = Input(1, #1)       ' 读入一字符。
    Next NextChar
    Close #1   

    4、Seek 函数

    语法:Seek(filenumber)

    功能:返回一个 Long,在 Open 语句打开的文件中指定当前的读/写位置。

    说明:在使用Get语句读取文件时,必须用LOF函数来判断是否到达文件末尾,而不是用EOF函数。可以使用Seek函数判断当前位置,然后与LOF的值比较。

    示例:
    Do While Seek(1) < LOF(1)
        '继续读取
        ......
    Loop


    (五)总结

           VBA语句的文件操作涵盖了文件操作的绝大部分内容,很多函数的使用也很简单,一般的文件读写也非常方便,特别是对文本文件。但对于复杂的文件读写,代码的结构和维护性都不好。因此在VB6之后,微软引入了FileSystemObject对象模型,提供了面向对象的类库,来操作驱动器、文件夹和文件。但对于二进制文件的操作,目前还只能用VBA语句。
           Excel文件本身就是二进制文件,它使用的文件格式叫做BIFF(Binary Interchange File Format),即二进制可交换文件格式(但2007开始使用OOXML格式)。关于其内部的结构,本人也在研究中。以二进制结构打开Excel文件,不但可以读取其表格中的数据,还可以读取其所有的信息(包括密码)。注意,以Open语句打开文件,并不是我们通常的双击一个文件打开显示到屏幕上,而是将其存放在磁盘上的数据读入到缓冲区,不是可视化的打开。这种打开是不需要密码的,即使你的Excel文件设置了打开密码,还是照打开不误,这也正是Excel文件不安全的根源所在。

    展开全文
  • Java如何正确的使用try catch finally关闭文件流的总结

    万次阅读 多人点赞 2016-09-05 14:10:45
    上学的时候,也许老师告诉你用完文件流记得要关闭,可能为了省事,他也没仔细的给你示范如何关闭,实际开发中,要是不能正确关闭流,服务器分分钟炸掉,那是很正常的。一般都是新人才会有这个问题。当然都是从新人走...

    上学的时候,也许老师告诉你用完文件流记得要关闭,可能为了省事,他也没仔细的给你示范如何关闭,
    实际开发中,要是不能正确关闭流,服务器分分钟炸掉,那是很正常的。
    一般都是新人才会有这个问题。当然都是从新人走过来的嘛。
    下面是大师兄总结的关闭文件流的基本动作,有不合适的,还请指出来。

    流在try外面声明,在try里面初始化,然后在finally里面给close,还记得处理异常e
    finally里面close的时候也得再次try catch 一下。
    具体代码和具体的解释如下:

        /**
         * 测试正确关闭文件流
         */
        private static void testCloseFileStream() {
            final Logger LOG = LoggerFactory.getLogger(Cmshome.class);
            String fileName = "";
            InputStream inputStream = null;//声明个引用,因为这个new对象的时候也是会异常的
            try {
                //这里就会异常,如果文件名不存在的话。
                inputStream = new FileInputStream(fileName);
            } catch (IOException e) {
                //这个主要是把出现的异常给人看见,不然就算异常了,看不到就找不到问题所在。
                LOG.debug("loadProperties IOException:" + e.getMessage());
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close(); // 关闭流
                    } catch (IOException e) {
                        LOG.debug("inputStream close IOException:" + e.getMessage());
                    }
                }
            }
        }
    
    
    	//错误的关闭文件的方式的解释:
    	Properties properties = new Properties();
    	try {
    		//这要是异常,直接就到catch语句,下面的close就不会执行啦,关闭就没用啦
    		InputStream wrongWay = new FileInputStream(fileName);
    		properties.load(wrongWay);
    		wrongWay.close(); // 关闭流
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    
    	//下面是new文件流和关闭文件流的源码,有抛异常动作。
        public FileInputStream(String name) throws FileNotFoundException {
            this(name != null ? new File(name) : null);
        }
    
    	//这个是抽象类(abstract class)里面的方法,所以没有具体实现过程。
        public void close() throws IOException {}

    关于一楼的留言的更新:


    这是我的代码,是经过debugs分析的,就一条红线。

    然后下面是这个红线的详细描述。


    他说的这个是编码的问题,说,我这个读文件的操作,是按默认的编码读的,警告我,选个好点的api,设置上指定的api,这样就可以很好的跨平台使用。并没有说,这个关文件流的毛病。

    展开全文
  • BIND配置文件详解options语句

    千次阅读 2017-11-01 19:52:52
    options语句options语句的定义和使用:options...这个语句在每个配置文件中只有一处。如果出现多个options语句,则第一个options的配置有效,并且会产生一个警告信息。 如果没有options语句,则每个选项使用缺省值。

    options语句

    options语句的定义和使用:

    options语句用来设置可以被整个BIND使用的全局选项。这个语句在每个配置文件中只有一处。如果出现多个options语句,则第一个options的配置有效,并且会产生一个警告信息。
    如果没有options语句,则每个选项使用缺省值。
    options {
    [ version version_string; ]
    [ directory path_name; ]
    [ named-xfer path_name; ]
    [ tkey-domain domainname; ]
    [ tkey-dhkey key_name key_tag; ]
    [ dump-file path_name; ]
    [ memstatistics-file path_name; ]
    [ pid-file path_name; ]
    [ statistics-file path_name; ]
    [ zone-statistics yes_or_no; ]
    [ auth-nxdomain yes_or_no; ]
    [ deallocate-on-exit yes_or_no; ]
    [ dialup dialup_option; ]
    [ fake-iquery yes_or_no; ]
    [ fetch-glue yes_or_no; ]
    [ has-old-clients yes_or_no; ]
    [ host-statistics yes_or_no; ]
    [ minimal-responses yes_or_no; ]
    [ multiple-cnames yes_or_no; ]
    [ notify yes_or_no | explicit; ]
    [ recursion yes_or_no; ]
    [ rfc2308-type1 yes_or_no; ]
    [ use-id-pool yes_or_no; ]
    [ maintain-ixfr-base yes_or_no; ]
    [ forward ( only | first ); ]
    [ forwarders { ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; … ] }; ]
    [ check-names ( master | slave | response )( warn | fail | ignore ); ]
    [ allow-notify { address_match_list }; ]
    [ allow-query { address_match_list }; ]
    [ allow-transfer { address_match_list }; ]
    [ allow-recursion { address_match_list }; ]
    [ allow-v6-synthesis { address_match_list }; ]
    [ blackhole { address_match_list }; ]
    [ listen-on [ port ip_port ] { address_match_list }; ]
    [ listen-on-v6 [ port ip_port ] { address_match_list }; ]
    [ query-source [ address ( ip_addr | * ) ] [ port ( ip_port | * ) ]; ]
    [ max-transfer-time-in number; ]
    [ max-transfer-time-out number; ]
    [ max-transfer-idle-in number; ]
    [ max-transfer-idle-out number; ]
    [ tcp-clients number; ]
    [ recursive-clients number; ]
    [ serial-query-rate number; ]
    [ serial-queries number; ]
    [ transfer-format ( one-answer | many-answers ); ]
    [ transfers-in number; ]
    [ transfers-out number; ]
    [ transfers-per-ns number; ]
    [ transfer-source (ip4_addr | *) [port ip_port] ; ]
    [ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
    [ notify-source (ip4_addr | *) [port ip_port] ; ]
    [ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
    [ alsonotify { ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; … ] }; ]
    [ max-ixfr-log-size number; ]
    [ coresize size_spec ; ]
    [ datasize size_spec ; ]
    [ files size_spec ; ]
    [ stacksize size_spec ; ]
    [ cleaning-interval number; ]
    [ heartbeat-interval number; ]
    [ interface-interval number; ]
    [ statistics-interval number; ]
    [ topology { address_match_list }];
    [ sortlist { address_match_list }];
    [ rrset-order { order_spec ; [ order_spec ; … ] } };
    [ lame-ttl number; ]
    [ max-ncache-ttl number; ]
    [ max-cache-ttl number; ]
    [ sig-validity-interval number ; ]
    [ min-roots number; ]
    [ use-ixfr yes_or_no ; ]
    [ provide-ixfr yes_or_no; ]
    [ request-ixfr yes_or_no; ]
    [ treat-cr-as-space yes_or_no ; ]
    [ min-refresh-time number ; ]
    [ max-refresh-time number ; ]
    [ min-retry-time number ; ]
    [ max-retry-time number ; ]
    [ port ip_port; ]
    [ additional-from-auth yes_or_no ; ]
    [ additional-from-cache yes_or_no ; ]
    [ random-device path_name ; ]
    [ max-cache-size size_spec ; ]
    [ match-mapped-addresses yes_or_no; ]
    };

    version

    回答针对服务器版本的请求时的内容。缺省返回的是服务器的真实版本。

    directory

    服务器的工作目录。配置文件中所有使用的相对路径,指的都是在这里配置的目录下。大多数服务器的输出文件(如named.run)都缺省生成在这个目录下。如果没有设定目录,工作目录缺省设置为服务器启动时的目录‘.’。指定的目录应该是一个绝对路径。

    named-xfer

    这个选项已经被废弃了。它在BIND8 中,它用来给named-xfer程序设定路径名。在BIND9中,不需要单独的named-xfer程序;它的功能已经内置在域名服务器中。

    tkey-domain

    这个域名将会附带在由TKEY 生成的所有共享密匙名字的后面。当用户请求进行TKEY交换时,它会为密匙设定或不设定所要求的名称。如果设置了tkey_domain,共享密匙的名字将会是”client specified part”(用户设定的部分)+ “tkey-domain”。否则,共享密匙的名字将是”random hex digits”(随机的16 进制数)+ “tkey-domain”。在大多数情况下,domainname应该是服务器的域名。

    tkey-dhkey

    针对使用Diffie-Hellman 的TKEY模式的用户,服务器用来生成共享密匙的Diffie-Hellman 密匙。服务器必须可以从工作目录中调入公共和私人密匙。大多数情况下,密匙的名称应该是服务器的主机名。

    dump-file

    当执行rndc dumpdb命令时,服务器存放数据库文件的路径名。如果没有指定,缺省名字是named_dump.db。

    memstatistics-file

    服务器输出的内存使用统计文件的路径名。如果没有指定,默认值为###named.memstats。
    注意:还没有在BIND9中实现!

    pid-file

    进程ID文件的路径名。如果没有指定,默认为/var/run/named.pid。pid-file是给那些需要向运行着的服务器发送信号的程序使用的。

    statistics-file

    当使用rndc stats命令的时候,服务器会将统计信息追加到的文件路径名。如果没有指定,默认为named.stats在服务器程序的当前目录中。

    port

    服务器用来接收和发送DNS协议数据的UDP/TCP端口号。默认为53。这个选项主要用于服务器的检测;因为如果不使用53端口的话,服务器将不能与其它的DNS进行通讯。

    random-device

    服务器使用的entropy源:entropy主要用于DNSSEC操作,如TKEY的数据交换和加密域的动态更新。此选项指定了entropy将会从哪个设备(或文件)中读取信息。如果它是一个文件,则当文件耗尽后,需要entropy的操作将会失败。如果没有指定,默认值是/dev/random(或等价的),如果它存在,否则就是没有。random-device选项是在服务器启动时,初始化配置时起作用的,在以后的重启时则被忽略。

    A.Boolean 选项

    auth-nxdomain
    如果是yes,那么AA位将一直设置成NXDOMAIN响应,甚至在服务器不是授权服务器的情况下都是这样的。默认值是no;这与BIND8不同。如果用户使用的是非常老版本的DNS软件,则有必要把它设置成yes。
    deallocate-on-exit
    此选项在BIND8中用于检查出口处内存泄露。BIND9忽略此选项,并始终进行检查。
    dialup
    如果是yes,那么服务器将会像在通过一条按需拨号的链路进行域传送一样,对待所有的域(按需拨号就是在服务器有流量的时候,链路才连通)。根据域类型的不同它有不同的作用,并将集中域的维护操作,这样所有有关的操作都会集中在一段很短的时间内完成,每个heartbeat-interval一次,一般是在一次调用之中完成。它也禁止一些正常的域维护的流量。默认值是no。
    dialup选项也可以定义在view和zone语句中,这样就会代替了全局设置中dialup的选项。
    如果域是一个主域,服务器就会对所有辅域发送NOTIFY请求。这将激活辅域名服务器中的对域的序列号的检验。这样当建立一个连接时,辅域名服务器才能确认这个域的传输合法性。
    如果这个域是一个辅域或是末梢域(stub zone),那么服务器将会禁止通常的“zone up to date”(refresh)请求,为了能发送NOTIFY请求,只有在heartbeat-interval 过期之后才执行。
    通过下列的设置,可以实现更好的控制。
    1、notify 只发送NOTIFY信息。
    2、notify-passive 发送NOTIFY信息,并禁止普通的刷新(refresh)请求。
    3、refresh 禁止普通的刷新处理,当heartbeat-interval 过期时才发送刷新请求。
    4、passive 只用于关闭普通的刷新处理。
    fake-iquery
    在BIND8中,此选项用来模拟陈旧的DNS查询类型IQUERY。BIND9不再进行IQUERY模拟。
    fetch-glue
    这个选项以后不再使用。
    has-old-clients
    这个选项在BIND8中执行有问题,BIND9则忽略了这个选项。为了达到has-old-clients yes的预期效果,可以设定两个独立选项auth-nxdomain yes和rfc2308-type1 no来代替。
    host-statistics
    在BIND8中,它可以保留每台和域名服务器交互的主机统计信息。BIND9中不支持。
    maintain-ixfr-base
    此选项不再使用了。在BIND8用于判定是否保存了增量域传输的处理日志。BIND9任何可能的时候都会保存传输日志。如果需要禁止流出的增量域传输,可以使用provide-ixfr no。
    minimal-responses
    如果是yes,当产生响应的时候,服务器将只会按照需要将记录添加到authority和additional的数据部分。(例如,delegations,negative responses)。这样会改善服务器的性能。默认值为no。
    multiple-cnames
    这个选项在BIND8中使用,允许一个域名承认多条CNAME记录(与DNS标准相违
    背)。BIND9.2在主hosts文件和动态更新中都严格强制执行CNAME规则。
    notify
    如果是yes(默认),当一个授权的服务器修改了一个域后,DNS NOTIFY信息被发送出去。此信息将会发给列在域NS记录上的服务器(除了由SOA MNAME标示的主域名服务器)和任何列在also-notify选项中的服务器。
    如果是explicit,则notify将只发给列在also-notify中的服务器。如果是no,就不会发出任何报文。
    notify选项也可能设定在zone语句中,这样它就替代了options中的notify 语句。如果notify会使得辅域名服务器崩溃,就需要将此选项关闭。
    recursion
    如果是yes,并且一个DNS询问要求递归,那么服务器将会做所有能够回答查询请求的工作。如果recursion是off的,并且服务器不知道答案,它将会返回一个推荐(referral)响应。默认值是yes。注意把recursion设为no,不会阻止用户从服务器的缓存中得到数据,它仅仅阻止新数据作为查询的结果被缓存。服务器的内部操作还是可以影响本地的缓存内容,如NOTIFY地址查询。
    rfc2308-type1
    设置成yes 将会使得服务器发送NS 记录和关于negative answer 的SOA记录。默认值为no。
    注:BIND9 中还不支持。
    use-id-pool
    此选项已经不再使用。BIND9 始终都是从池中分配请求ID的。
    zone-statistics
    如果是yes,缺省情况下,服务器将会收集在服务器所有域的统计数据。这些统计数据可以通过使用rndc stats来访问,rndc stats命令可以将这些信息转储到statistics-file定义的文件中去。
    use-ixfr
    这个选项不再使用。如果需要针对一个或多个特殊的服务器关闭IXFR,可以参考provide-ixfr中的内容。
    provide-ixfr
    参阅中关于provide-ixfr的陈述。
    request-ixfr
    参阅关于request-ixfr的陈述。
    treat-cr-as-space
    这个选项应用于BIND8中,使服务器正确处理回车(”\r”)字符,就象其它的空格或tab字符一样。这样可以便于在unix系统上加载由NT或DOS系统生成的域文件。在BIND9中,UNIX”的\n”和DOS 的”\r\n”都可以正确处理为换新行,这个选项就被忽略了。
    additional-from-auth
    additional-from-cache
    当回答具有additional数据的请求,或者当在CNAME 和DNAME串的后面时,这些选项控制一个权威服务器的操作。
    当这两个选项都被设成yes(默认状态),并且查询的是授权的数据(这个域就配置在本地服务器中)时,回答中的additional部分的数据将使用来自于其它授权域和cache。
    在许多情况下这是不需要的,比如在缓存内容的正确性受到怀疑的情况下,或是在某些辅域可能被非法修改的服务器。还有,避免对这些additional数据的搜索将会加速服务器运转。
    例如,如果一个查询需要主机foo.example.com的MX记录,找到的记录是”MX 10
    mail.example.net”,如果知道的话, mail.example.net的地址记录(A,A6 和AAAA)也会被提供出来。把选项设置为no,则禁止了这种操作。
    这些选项用于授权的服务器,或者是授权的视图中。把它们设成no,但没有同时设置recursion no,将会使得服务器忽略这些选项,并记录一个警告日志。
    设定additional-from-cache为no实际上针对additional信息的查询和正在响应的查询,都禁止了缓存的使用。这常常使用在一台授权的服务器中,因为在这里缓存数据的正确性非常重要。
    当一台域名服务器不提供递归查询时,并且查询的名称并不在本地域中,一般会对根服务器或者其他已知的上级服务器回答”upwards referral(向上推荐)”。既然在向上查询中的数据来自于缓存,那么当additional-from-cache被设定为no时,服务器就不能提供向上推荐。相反,它会使用REFUSED(拒绝)回答这些查询。因为向上推荐不是在用户解析过程中需要的,所以就不会出任何问题。
    match-mapped-addresses
    如果是yes,那么一个ipv4映射成的ipv6地址就会匹配任何地址匹配表中能匹配于对应的ipv4 地址的记录。打开这个选项,对于运行了ipv6的linux系统有时非常有用,这样通过地址映射,就可以使得ipv4的TCP连接(如域传送)实现在Ipv6的soket上,因为地址匹配列表是给Ipv4设计的。

    B. 转发

    转发功能可以用来在一些服务器上产生一个大的缓存,从而减少到外部服务器链路上的流量。它可以使用在和internet没有直接连接的内部域名服务器上,用来提供对外部域名的查询。只有当服务器是非授权的,并且缓存中没有相关记录时,才会进行转发。
    forward
    此选项只有当forwarders列表中有内容的时候才有意义。当值是First,默认情况下,使服务器先查询设置的forwarders,如果它没有得到回答,服务器就会自己寻找答案。如果设定的是only,服务器就只会把请求转发到其它服务器上去。
    forwarders
    设定转发使用的ip地址。默认的列表是空的(不转发)。转发也可以设置在每个域上,这样全局选项中的转发设置就不会起作用了。用户可以将不同的域转发到服务器上,或者对不同的域可以实现forward only或first的不同方式,也可以根本就不转发。

    C. 访问控制

    可以根据用户请求使用的IP地址进行限制。

    allow-notify

    设定哪个主机上的辅域(不包括主域)已经进行了修改。allow-notify也可以在zone语句中设定,这样全局options中的allow-notify选项在这里就不起作用了。但它只对辅域有效。如果没有设定,默认的是只从主域发送notify信息。

    allow-query

    设定哪个主机可以进行普通的查询。allow-query也能在zone语句中设定,这样全局options中的allow-query选项在这里就不起作用了。默认的是允许所有主机进行查询。

    allow-recursion

    设定哪台主机可以进行递归查询。如果没有设定,缺省是允许所有主机进行递归查询。注意禁止一台主机的递归查询,并不能阻止这台主机查询已经存在于服务器缓存中的数据。

    allow-v6-synthesis

    设定哪台主机能接收对ipv6的响应。
    allow-transfer
    设定哪台主机允许和本地服务器进行域传输。allow-transfer也可以设置在zone语句中,这样全局options中的allow-transfer选项在这里就不起作用了。如果没有设定,默认值是允许和所有主机进行域传输。
    blackhole
    设定一个地址列表,服务器将不会接收来自这个列表的查询请求,或者解析这些地址。从这些地址来的查询将得不到响应。默认值是none。

    D. 接口

    接口和端口(服务器回答来自于此的询问)可以使用listen-on选项来设定。listen-on使用可选的端口和一个地址匹配列表(address_match_list)。服务器将会监听所有匹配地址列表中所允许的端口。如果没有设定端口,就使用默认的53。
    允许使用多个listen-on语句。例如:
    listen-on { 5.6.7.8; };
    listen-on port 1234 { !1.2.3.4; 1.2/16; };
    将在5.6.7.8 的ip地址上打开53端口,在除了1.2.3.4的1.2 网段上打开1234 端口。
    如果没有设定listen-on,服务器将在所有接口上监听端口53。
    listen-on-v6选项用来设定监听进入服务器的ipv6请求的端口。
    服务器并不象在ipv4中那样对每个IPV6端口地址绑定一个独立的socket。相反,它一直监听ipv6通配的地址。这样,对于listen-on-v6语句唯一的address_match_list的参数就是:{ any; }和{ none;}
    多个listen-on-v6选项可以用来监听多个端口:
    listen-on-v6 port 53 { any; };
    listen-on-v6 port 1234 { any; };
    要使服务器不监听任何ipv6地址,使用:
    listen-on-v6 { none; };
    如果没有设定listen-on-v6语句,服务器将不会监听任何ipv6地址。

    E. 查询地址

    如果服务器查不到要解析的地址,它将会查询其它域名服务器。query-source可以用来设定这类请求所使用的地址和端口。对于使用ipv6发送的查询,有一个独立的query-source-v6选项。如果address是*或者被省略了,则将会使用一个通配的IP地址
    (INADDR ANY)。如果port是*或者被省略了,则将会使用一个随机的大于1024的端口。
    默认为:
    query-source address * port *;
    query-source-v6 address * port *;
    注:query-source选项中设置的地址是同时用于UDP和TCP两种请求的,但是port仅仅用
    于UDP请求。TCP请求使用的是随机的大于1024的端口。

    F. 域传输

    BIND有适当的机制来简化域传输,并限定系统传输的负载量。下列设定应用于域传输:
    also-notify
    定义一个用于全局的域名服务器IP地址列表。无论何时,当一个新的域文件被调入系统,域名服务器都会向这些地址,还有这些域中的NS记录发送NOTIFY信息。这有助于更新的域文件尽快在相关的域名服务器上收敛同步。如果一个also-notify列表配置在一个zone语句中,全局options中的also-notify语句就会在这里失效。当一个zone-notify语句被设定为no,系统就不会向在全局中also-notify列表中的IP地址发送NOTIFY消息。缺省状态为空表(没有全局通知列表)。
    max-transfer-time-in
    比设定时间更长的进入的域传输将会被终止。默认值是120分钟(2小时)。
    max-transfer-idle-in
    在设定时间下没有任何进展的进入域传输将会被终止。默认为60分钟(1小时)。
    max-transfer-time-out
    运行时间比设定的时间长的发出的域传输将会被终止。默认为120分钟(2小时).
    max-transfer-idle-out
    在设定时间下没有任何进展的发出的域传输将会被终止。默认为60分钟(1小时)。
    serial-query-rate
    辅域名服务器将会定时查询主域名服务器,来确定域的串号是否改变。每个查询将会占用一些辅域名服务器网络带宽。为限制占用的带宽,BIND9可以限制每个查询发送的频率。serial-query-rate的值是一个整数,就是每秒能发送的最大查询数。默认值为20。
    serial-queries
    在BIND8中, serial-queries选项设定了在任何时候允许达到的最大的并发查询数。BIND9不限制串号查询的数量并忽略了serial-queries选项。它会使用serial-query-rate选项来限制查询的频率。
    transfer-format
    域传输可以用两种不同格式,one-answer和many-answer。transfer-format选项使用在主域名服务器上,用来确定发送哪种格式。one-answer在每个资源记录传输中使用一个
    DNS消息。many-answer则将尽可能多的资源记录集中在一个消息中。many-answer是
    更加有效的,但只有相对比较新的辅域名服务器才支持它,如BIND9、BIND8.x 和打了补丁的BIND4.9.5。默认的设置为many-answer。使用server语句中的相关选项,可以替代全局选项中的transfer-format设置。
    transfers-in
    可以同时运行的进入的域传输的最大值。默认值为10。增加transfers-in的值,可以加速辅域的收敛速度,但也可能增加本地系统的负载。
    transfers-out
    可以同时运行的发出的传输的最大值。超过限定的域传输请求将会被拒绝。默认值为10。
    transfers-per-ns
    从一台指定的远程域名服务器,同时进行的进入的域传输的最大值。默认值2。增加
    transfers-per-ns的值,会加速辅域的收敛速度,但也可能增加远程系统的负载。使用
    server语句中的transfer短语可以替代全局选项中的transfers-per-ns。
    transfer-source
    transfer-source决定在从外部域名服务器上得到域传送数据时,选哪个本地的ip地址使用在IPV4的TCP连接中。它可以选定IPV4的源地址,和可选的UDP端口,用于更新的查询和转发的动态更新。不过不做设置,它会缺省挑选一个系统中的地址(常常是最靠近远程终端服务器的接口地址)。但这个地址必须已经配置在远程终端的allow-tranfer选项中,才能进行域传送。此语句为所有的域设定了transfer-source,但如果view或zone中也使用了transfer-source语句,则全局选项中的配置就在这里失效了。
    transfer-source-v6
    和transfer-source一样,只是域传输是通过IPV6执行的。
    notify-source
    notify-source确定使用哪些本地的源地址和可选的UDP端口,用于发送NOTIFY消息。这个地址必须在辅域名服务器的master域或在allow-notify中设置。它会为所有域设定
    notify-source, 但如果view或zone中也使用了notify-source语句,则全局选项中的配置就在这里失效了。
    notify-source-v6
    与notify-source类似,但应用于ipv6地址的notify报文的发送。

    G. 操作系统资源限制

    可以限制服务器对许多系统资源的使用。这些就是通过调节资源限制的数值来完成的。例如,1G可以代替1073741824,限定一个十亿字节的限制。Unlimited 要求不限制使用,或者最大可用量。Default 将会使用服务器启动时的缺省值。
    下列选项设定了域名服务器进程的操作系统资源占用限制。一些操作系统可能不支持一些
    或所有的限制。在这样的系统中,当使用不被支持的限制时,会产生一个告警。
    coresize
    core dump文件的最大值尺寸。默认值为default
    datasize
    服务器可以使用的最大数据内存量。默认值为default。这是一个在服务器系统内存中
    已经设置了的参数。如果服务器要超过这个限制的内存量,则会失败,这将使服务器不能
    提供DNS服务。所以,这个选项作为一种限制服务器所使用的内存量的方式就不太有效,但是它能够将操作系统设置的太小的缺省数据尺寸增大。如果要限制服务器使用的内存量,可以使用max-cache-size和recursive-clients选项。
    files
    服务器可以同时打开的最大文件数。默认是unlimited。
    stacksize
    服务器可以使用最大的堆栈内存量。默认值为default。

    H. 服务器资源限制

    下列选项设定了服务器资源使用限制,这是由域名服务内部做的而不是操作系统设定的。
    max-ixfr-log-size
    此选项比较老;它由BIND8兼容接受或者忽略。
    recursive-clients
    服务器同时为用户执行的递归查询的最大数量。默认值1000,因为每个递归用户使用许多位内存,一般为20KB,主机上的recursive-clients选项值必须根据实际内存大小调整。
    tcp-clients
    服务器同时接受的TCP连接的最大数量,默认值100。
    max-cache-size
    服务器缓冲使用的最大内存量,用比特表示。但在缓存数据的量达到这个界限,服务器将会使记录提早过期这样限制就不会被突破。在多视图的服务器中,限制分别使用于每个视图的缓存。默认值没有限制,意味着只有当总的限制被突破的时候记录才会被缓存清除。

    I. 周期性任务间隔

    cleaning-interval
    服务器将在cleaning-interval的每一时间中从缓存中清除过期的资源记录。默认为60分钟,如果设置为0,就不会有周期性清理。
    heartbeat-interval
    服务器将会为所有标记dialup的域运行维护任务,无论它的间隔在何时到期。默认为60分钟,合理值不超过1天(1440 分钟)。如果设定为0,不会为这些域产生域维护。
    interface-interval
    服务器将在每个interface-interval时间扫描网络接口表。默认为60分钟。如果设置为0,仅当配置文件被加载时才会进行接口扫描。在扫描之后,所有新接口上的监听器将会被打开(listen-on配置使用的接口)。关闭接口上的监听器将会被清除。
    statistics-interval
    域名服务器统计将会在每个statistics-interval时刻被记入日志。默认值60分钟,如果设为0,就没有统计数据记入日志。
    注意:BIND9 不支持

    J. 拓扑

    当服务器从一个域名服务器列表中选择一个域名服务器查询时,这些域名服务器是没有什么不同的,但是服务器会先选择在拓扑结构上距离自己最近的服务器去做解析。拓扑语句使用一个地址匹配列表并且以一个特殊方式解释它。每个顶层列表元素被赋了一段距离,非否定元素得到它们在列表中的位置的距离,匹配距离表的开头越近,它离服务器的距离就越小。否定匹配元素将会从服务器分配最大距离;没有匹配的地址将会得到一个比任何非否定表元素都远的并且比任何否定元素近的距离。例如:
    topology {
    10/8;
    !1.2.3/24;
    { 1.2/16; 3/8; };
    };
    最优先网段10的服务器,然后是在网络1.2.0.0(网络掩码255.255.0.0)和3.0.0.0(网络掩
    码255.0.0.0);再就是没列出来的,但是没有否定的网段。否定的网段1.2.3 的主机(网络掩
    码255.255.255.0)。
    默认拓扑为:
    topology { localhost; localnets; };
    注意:BIND9不支持拓扑选项。

    K. sortlist 语句

    对一个DNS询问的响应包括形成一个资源记录集(RR集)的多资源记录(RRs)。名称服务器将会以不确定的顺序返回在RRset中的RRs(参见rrset-order语句)。用户端的解答器会重新适当的排列,也就是说,使用任何在本地网上的地址优先于其他的地址。尽管如此,不是所有的解答器可以做到或者正确配置。当用户使用一个本地服务器的时候,服务器可以基于用户地址进行分类。这只要求配置名称服务器,而不是所有用户端。
    sortlist语句(如下)使用一个地址匹配表甚至比拓扑语句还要特殊的解释它。每个在sortlist 的顶层语句必须自己就是一个清楚的拥有一个或两个元素的地址匹配表。每个顶级表的第一个元素(可能是一个IP地址,一个IP前缀,一个ACL名称或者一个地址匹配表)与查询源地址进行匹配检查直到找到匹配的地址。
    一旦查询的源地址被匹配,如果顶级语句只包括一个元素的话,真正的匹配于源地址的原始元素就被用来选择地址,对应的转移到了响应的开始。如果语句是两个元素的表,那么第二个元素遵照拓扑语句中地址匹配表的方式进行处理。每个顶级元素被赋予一个距离和与响应的开头距离最近的地址。
    在下列例子中,任何来自于任何主机地址的查询将会得到本地网上第一首选地址的响应。下一个首选地址在网段192.168.1/24上,既可以在192.168.2/24或192.168.3/24网段之后。从一台在192.168.1/24网段上的主机收到的查询将会优先本网段和192.168.2/24和192.168.3/24网。而来自192.168.4/24或192.168.5/24上主机的查询将只优先直连的网段。
    sortlist {
    { localhost; //IF 主机名
    { localnets;
    192.168.1/24; //THEN 在下列网中最适合
    { 192.168.2/24; 192.168.3/24; }; }; }; //IF 在C类192.168.1
    { 192.168.1/24; //THEN 使用.1, 或.2 或.3
    { 192.168.2/24; 192.168.3/24; }; }; };
    { 192.168.2/24; //IF C类192.168.1
    { 192.168.2/24; //THEN使用2, 或.1 或.3
    { 192.168.1/24; 192.168.3/24; }; }; };
    { 192.168.3/24; //IF 在C类192.168.3
    { 192.168.1/24; 192.168.2/24; }; }; }; //THEN使用.3 或.1 或.2
    };
    };
    下个例子将给出一个本地主机和直接连接到网上的主机的合理的状态(behavior)。它很象BIND4.9.x分类的地址状态。从本地主机发给查询的响应支持任何直接连接的网络,从其他直接连接网络上的主机发送给查询的响应优先在相同网段上的地址。对其他查询的响应没有分类。
    sortlist {
    { localhost; localnets; };
    { localnets; };
    };

    L. RRset 排序
    当多重记录在一个解答中被返回的时候,设定在响应中的记录顺序是很有用的.。
    rrset-order语句允许对在多记录响应下的记录顺序的设定。参见sortlist语句。
    一个order_spec定义如下:
    [ class class_name ][ type type_name ][ name “domain_name”] order ordering
    如果没有设定类,默认值为ANY。如果没有设定类型,默认值为ANY。如果没有设定
    名称,默认值为”*”。
    合法的排序值是:
    fixed:记录以它们在域文件中的顺序
    random:记录以随机顺序被返回
    cyclic:记录以环顺序被返回
    例如:
    rrset-order {
    class IN type A name “host.example.com” order random;
    order cyclic;
    };
    将会使得任何处于IN类中的A类记录的响应以随机顺序返回,IN 类以”host.example.com”为后缀。其他的记录以循环记录被返回。
    如果多重rrset-order语句出现,它们并不组合在一起,只适用于最后一个条。
    注意:rrset-order语句不被BIND9支持,BIND9目前只支持”random-cyclic”排序,服务器随机选择RRset集中的开始点,有顺序返回在那个点开始的记录。如果需要的话围绕RRset
    结尾。

    M. 合成的IPV6响应

    许多现存的子域解答器支持ipv6的DNS查询(定义在RFC1986 中,使用AAAA 记录进行前向查询和ip6.int域中的”nibble labels”进行反向查询)但是不支持RFC2874-style 查询(使用A6记录和在ip6.arpa 中的二进制标签)对于那些希望继续使用子域解答器而不是转到
    BIND9 lightweight 解答器的人来说,BIND 9提供一种自动把RFC1886-型查询转换成
    RFC2874-型查询的方法。返回合成的AAAA和PTR记录。
    这个性质默认下是无效的,可以在分用户基础上添加一个allow-v6-synthesis
    { address_match_list };子句到选项或者视图语句中。当它被激活时,递归AAAA查询使服
    务器先进行A6查询,如果失败,执行AAAA查询。不管哪个成功,结果都作为一个合成的AAAA 记录返回。
    类似的,在ip6.int中的递归PTR查询将会促使一个ip6.arpa查询使用二进制标签,如果失败,执行另一个在ip6.int中的查询,结果将会以在ip6.int中的合成PTR记录返回。合成记录的TTL 为0值。合成响应的DNSSEC确认当前并不被支持;也没有了AD标记。
    注:allow-v6-synthesis仅为提供了递归服务的用户执行。

    N. 调谐

    lame-ttl
    设定缓存有问题服务器指示的秒数。0使不缓存(不被推荐)。默认值600(10 分钟)。最大值1800(30 分钟)。
    max-ncache-ttl
    为降低网络流量和提升服务器存储否定回答的性能。max-ncache-ttl以秒为单位设定这些回答的保存时间。默认max-ncache-ttl是10800秒(3小时)。max-ncache-ttl不能超过7天,如果设成一个更大的值,则将会被自动减为7天。
    max-cache-ttl
    max-cache-ttl设定了服务器储存普通(肯定)答案的最大时间。默认值一周(7 天)。
    min-roots
    一个请求要求的最小的根服务器数量。默认为2。
    注意:不被BIND9 支持
    sig-validity-interval
    设定未来作为动态更新结果的自动生成的DNSSEC信号过期的天数。默认是30天。信号的初始时间无条件设为在当前时间的前一个小时,以允许一个有限的时钟偏差。
    min-refresh-time
    max-refresh-time
    min-retry-time
    max-retry-time
    这些选项控制了服务器在更新一个域(询问SOA变化)或者重试失败的传输时的状态。通常域的SOA值(但是这些值是由主服务器设定的)几乎不给此级服务器管理者对它们内容的控制。
    这些选项允许管理者为每域,每个视图或者全局设定一个最小或者最大更新和重试时间。这些选项对于此级和根域是有效的并且设定SOA更新和重试时间。

    O. 统计文件

    由BIND9产生的统计文件和由BIND8产生的类似,但不完全一样。
    一个统计数据开始于行+++ Statistics Dump +++ (973798949),这里出现的数字是一个标准UNIX型的时间戳,从1970年1月1日开始以秒计。紧跟这行的是一系列行,包括一个
    记数器类型,记数器值,任意的域名和任意的视图名,没有所列的视图和域的行是整个服务器的整体统计。具有域和视图的行以给定的视图和域命名(对默认的视图来说视图名缺省)。
    这个统计数据以行— Statistics Dump —(973798949)结束,在这数字是和开始行的数字一样的。Success对服务器或者域做出的成功查询。定义一个成功查询是查询返回非错误响应而不是返回推荐响应。
    Referral:导致推荐响应查询
    Nxrrset:导致没有数据的非错误查询的响应
    Nxdomain:导致NXDOMAIN 的查询数量
    Recursion:使服务器运行递归以找出最后答案的查询数量
    Failure:导致失败的查询数量

    展开全文
  • 要以读文件的模式打开一个文件对象,可使用Python内置的...文件使用完毕后必须调用close()关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的 由于文件读写时都有可能产生...
  • python文件读写,以后就用with open语句

    千次阅读 2018-06-25 16:32:30
    读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过...
  • 这个其实就是一个导出生成DBF文件的功能,实现思路是这样:首先动态拼接一个sql语句,执行后返回结果集到代码中,再通过dbfwriter对象把结果集的数据写到dbf文件里。 1、打开数据库连接,执行sql语句,获得结果集 ...
  • 3. 执行外部文件中的sql语句   方法一  使用cmd命令执行(windows下,unix或linux在的其控制台下)  【Mysql的bin目录】\mysql –u用户名 –p密码 –D数据库<【sql脚本文件路径全名】,示例:  D:\mysql\...
  • defer语句

    2016-07-30 17:38:05
    与select语句一样,Go语言中的defer语句也非常独特,而且比前者有过之而无不及。defer语句仅能被放置在函数或方法中。它由关键字defer和一个调用表达式组成。注意,这里的调用表达式所表示的既不能是对Go语言内建...
  • python---with语句

    2021-09-08 16:52:00
    with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确关闭,以此来达到释放资源的目的 with open('first.txt','r') as file: print(file.read()) 简单的说,就是省去了关闭文件的操作。所以...
  • with语句的工作机制

    2021-04-16 20:17:15
    运行结果: With实现机制: with对象有一个__enter__和__exit__方法 with语句首先调用对象的方法,并将方法的返回值赋给as后面的变量,当with后面的代码...程序遇到bug,如果使用with,python可保证文件正确关闭 ...
  • 有时我们需要用shell脚本处理一些文件,通常我们会使用awk这个强大的可编程命令来处理文本文件,当我们在一次awk调用中处理很多文件时,如果没有正确关闭打开的文件和管道,则会造成文件句柄泄露,文件awk命令会...
  • 异常处理语句

    千次阅读 2019-03-30 15:26:18
    异常处理语句throw语句catchfinally 语句try...catch..finally语句 try 语句测试代码块的错误。 catch 语句处理错误。 throw 语句创建自定义错误。 finally 语句在 try 和 catch 语句之后,无论是否有触发异常,该...
  • 因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在编程时确保在正确的时机关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用,数据库连接过多导致连接池溢出等诸多很严重的问题。...
  • 【C++入门系列】C++ Primer Plus 第六章分支语句和逻辑操作符的笔记 用例子阐释了 逻辑表达式,问号操作符,switch语句,break和continue以及文件简单输入输出
  • 1.for语句实验: <1>新建一个脚本,正序输出1~10 [root@shenzhen linux]# vim file.sh [root@shenzhen linux]# sh file.sh 脚本中的内容如下: #!/bin/bash for i in {1..10} do echo $i done 或者也...
  • Python with open语句

    千次阅读 2017-09-19 17:54:54
    在读写文件时为了保证无论是否出错都能正确关闭文件,我们可以使用try ... finally来实现: try: f = open('/path/to/file', 'r') print(f.read()) finally: if f: f.close()但是每次都这么写实在太繁琐,...
  • python中with语句的使用

    千次阅读 2017-09-10 20:08:09
    # 缩进取消,退出with语句块,表明文件操作结束,python自动关闭文件特点 with语句打开文件,并指示了一个语句块(即接下来有一个缩进的多行代码区域),该语句块内的代码是对文件的操作,当脱离该语句块时(即没有了
  • // 将出错语句写入到文件  writer.flush();  if (s.length + 1 ()) {  List<String> sList = sqlList.subList(s.length + 1, sqlList.size());  executesqls(sList);  }  } else {  e....
  • mysql正确关闭slave取消主从

    万次阅读 2019-01-10 10:31:39
    正确关闭slave步骤 执行STOP SLAVE语句 使用SHOW STATUS检查slave_open_temp_tables变量的值 如果值为0,使用mysqladmin shutdown命令关闭从服务器 如果值不为0,用START SLAVE重启从服务器线程 slave_open_...
  • MySQL load语句详细介绍

    千次阅读 2018-01-19 15:38:43
    通常,LOAD DATA INFILE的速度会非常快,但是在某些极端情况下,您可以在把文件载入到表中之前使用ALTER TABLE...DISABLE KEYS关闭LOAD DATA INFILE,或者在载入文件之后使用ALTER TABLE...ENABLE KEYS再次创建...
  • 于是就靠着之前用过mssql的经验,先打开企业管理器进行添加数据库,不料报出:“错误 5172 :文件‘xxx’的文件头不是有效的数据库文件头。file size不正确。”于是就在网上找到一些资料,大体如下: 1.先建立一个...
  • MySQL常用sql语句

    千次阅读 2017-04-27 17:29:57
    1、使用sql对数据库操作 连接数据库命令: mysql -u root -p ...创建数据库:create database dbname; 查看所有的数据库:show databases; 删除数据库: drop database dbname;...创建数据库表:语句 create table tablen
  • mysql语句优化

    千次阅读 2015-12-08 13:03:21
    1.通过show ststus命令了解sql的执行效率 ...通过慢查询日志定位那些执行效率较低的 SQL 语句,用 --log-slow-queries[=file_name] 选项启动时, mysqld 会 写一个包含所有执行时间超过 long_query_time
  • 关闭文件流,try..finally 和with语句
  • with语句的理解

    千次阅读 2018-07-24 15:42:40
    with语句的作用: with语句使用于对资源进行访问的场合。...比如文件使用后自动关闭,线程中锁的自动获取和释放。 参考:https://blog.csdn.net/u014745194/article/details/71424909 感谢作者...
  • Oracle11g重建控制文件

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 166,414
精华内容 66,565
关键字:

关闭文件的正确语句