其实删除文件主要需要知道两件事情: (1)被删除的行的前面那段数据的开始地址和结束地址,开始地址总是第一个字节,所以只要知道结束地址就可以了。 (2)被删除的行的后面那段数据的开始地址和结束地址,结束地址就是LOF(文件号),所以只要知道开始地址就可以了。 每当你用Line Input读文件一行的时候,有个看不到的文件指针在向后“移动”。所以,在顺序文件操作的时候,没有地址的参数,而是傻呼呼地一行一行向后读。每读一行,指针就向后面的地址移动。 在你读一个新文件的时候,第一次Input之前,指针一般都是1。那么你读了一行后,指针就是下一行的开始。Seek函数就是取指针的。而Seek语句可以定位顺序文件的指针。 根据这个特点,用Seek就可以得到两个最主要的要素:前段数据的结束地址,后段数据的起始地址。 得到后面的起始地址很简单,只要读到你所需要删除的行,那么Seek返回的就是它。而你所读的行的前一行的Seek返回的是你要删除的行的开始地址,减一就是前段数据的起始地址。Function GetSegAdd(pFileName As String,pLine as long,pPSegEnd as long,pBSegOn as long) 'pFileName文件名。 'pLine被删除的行。 'pPSegEnd前段的结束。 'pBSegOn后段的开始。 Dim tFN As Integer Dim tLoop As Long Dim tLineSegEnd As Long Dim tLineSegOn As Long Dim tLStr As String tFN=FreeFile Open pFileName For Input As #FN For tLoop=1 To pLine tLineSegOn=Seek(tFN)-1 Line Input #FN,tLStr tLineSegEnd=Seek(tFN) If EOF(tFN) Then Exit For Next Close #FN pPSegEnd=tLineSegOn pBSegOn=tLineSegEnd End Function 如何根据pPSegEnd和pBSegOn进行删除行的操作。这和切火腿肠一个道理。某日你发现一根火腿肠中间有脏东西,你想把这段去掉,怎么办呢?你要切两刀,把火腿切成三段。扔掉其中一段。而pPSegEnd和pBSegOn是刀口的位置。实际上你是取两段有用的火腿合在一起。那么一段火腿都需要两个头,前面的例子里你少切了两刀而已。少切那两刀,一刀是堵头,就是地址1,另一刀是结尾,就是LOF(文件号)。 进行后面的操作你需要一个通用的切火腿肠的函数,不管是不是堵头都切两刀,顶多有一刀是切空的。如下:Function GetSegBytesByFile(pFileName As String,pSegOn as long,pSegEnd as long,pOutBytes() As Byte) Dim tFN As Integer Dim tSegLong As Long tSegLong=Abs(pSegEnd-pSegOn) 'tSegLong是这段火腿的长度。 ReDim pOutBytes(tSegLong-1) '装这段火腿的马口铁罐头盒(后面你就知道为什么叫罐头盒了) tFN=FreeFile Open pFileName For Binary As #FN Get #tFN,pSegOn,pOutBytes 'pSegOn是开始的地址。而长度是pOutBytes无形中指定的。 '你只要把马口铁罐头盒一头对准开始的地方一压就可以了,这样保证切下来是一段火腿。回去找个午餐肉盒子实验一下。 Close #tFN End Function那么现在我们有了切火腿段的工具,也知道从什么地方下刀了。GetSegAdd tFileName,tLine,tPSegEnd,tBSegOn Dim tPBytes() as Bytes Dim tBBytes() As Bytes ReDim tPBytes(0) ReDim tBBytes(0) Dim tFN As Integer Open tNewFileName For Binary As #tFN tFileSize=GetFileSize(tFileName) '我想这个取文件长度的函数不用我教你怎么写了吧?用LOF就可以返回了。 GetSegBytesByFile tFileName,1,tPSegEnd,tPBytes() '切火腿的前头 GetSegBytesByFile tFileName,tBSegOn,tFileSize,tBBytes() '切火腿的后头 Put #tFN,1,tPBytes() '把第一段火腿放在前头。 Put #tFN,LOF(tFN),tPBytes() '把第二段火腿放在后头。如果有丢失一个字节数据的错误可以实验LOF(tFN)+1,我也懒得去实验到底该不该加一了。 Close #tFN 上面的函数没有测试过,只是给你说明原理。具体的可以运行的程序如果你一定要我帮你写,那就等我zzzZZZ一觉之后吧。熬了一夜游戏,我可困了!
整个把文件读一遍,一行一行的
边读边写,你不要的那一行,用if踢出去
然后先关闭源文件,在把你新写的文件重命名覆盖源文件
that's all.我始终坚信:简单的笨方法好过难解的、复杂的最优算法。所以
我的程序……呵呵
不写文件,只读文件,读到被删除的行。
每次读的时候做这样的操作:保留这行的开始地址,取下行的开始地址。这样你就可以通过计算得到2组信息:
1·前段的开始和结束地址。
2·后段的开始和结束地址。 然后用两次的Get和Put操作就可以完成删除行的操作。这个操作的好处在于:只读文件,不写文件。速度要稍微比上一个办法快一些,而VB当中除非有控件帮助,否则还真想不出什么更快的办法。
如果你是制作编辑软件,那可以在编辑态来完成而没必要在文件完成。
在你读一个新文件的时候,第一次Input之前,指针一般都是1。那么你读了一行后,指针就是下一行的开始。Seek函数就是取指针的。而Seek语句可以定位顺序文件的指针。
根据这个特点,用Seek就可以得到两个最主要的要素:前段数据的结束地址,后段数据的起始地址。
得到后面的起始地址很简单,只要读到你所需要删除的行,那么Seek返回的就是它。而你所读的行的前一行的Seek返回的是你要删除的行的开始地址,减一就是前段数据的起始地址。Function GetSegAdd(pFileName As String,pLine as long,pPSegEnd as long,pBSegOn as long)
'pFileName文件名。
'pLine被删除的行。
'pPSegEnd前段的结束。
'pBSegOn后段的开始。
Dim tFN As Integer
Dim tLoop As Long
Dim tLineSegEnd As Long
Dim tLineSegOn As Long
Dim tLStr As String
tFN=FreeFile
Open pFileName For Input As #FN
For tLoop=1 To pLine
tLineSegOn=Seek(tFN)-1
Line Input #FN,tLStr
tLineSegEnd=Seek(tFN)
If EOF(tFN) Then Exit For
Next
Close #FN
pPSegEnd=tLineSegOn
pBSegOn=tLineSegEnd
End Function 如何根据pPSegEnd和pBSegOn进行删除行的操作。这和切火腿肠一个道理。某日你发现一根火腿肠中间有脏东西,你想把这段去掉,怎么办呢?你要切两刀,把火腿切成三段。扔掉其中一段。而pPSegEnd和pBSegOn是刀口的位置。实际上你是取两段有用的火腿合在一起。那么一段火腿都需要两个头,前面的例子里你少切了两刀而已。少切那两刀,一刀是堵头,就是地址1,另一刀是结尾,就是LOF(文件号)。
进行后面的操作你需要一个通用的切火腿肠的函数,不管是不是堵头都切两刀,顶多有一刀是切空的。如下:Function GetSegBytesByFile(pFileName As String,pSegOn as long,pSegEnd as long,pOutBytes() As Byte)
Dim tFN As Integer
Dim tSegLong As Long
tSegLong=Abs(pSegEnd-pSegOn) 'tSegLong是这段火腿的长度。
ReDim pOutBytes(tSegLong-1) '装这段火腿的马口铁罐头盒(后面你就知道为什么叫罐头盒了)
tFN=FreeFile
Open pFileName For Binary As #FN
Get #tFN,pSegOn,pOutBytes 'pSegOn是开始的地址。而长度是pOutBytes无形中指定的。
'你只要把马口铁罐头盒一头对准开始的地方一压就可以了,这样保证切下来是一段火腿。回去找个午餐肉盒子实验一下。
Close #tFN
End Function那么现在我们有了切火腿段的工具,也知道从什么地方下刀了。GetSegAdd tFileName,tLine,tPSegEnd,tBSegOn
Dim tPBytes() as Bytes
Dim tBBytes() As Bytes
ReDim tPBytes(0)
ReDim tBBytes(0)
Dim tFN As Integer
Open tNewFileName For Binary As #tFN
tFileSize=GetFileSize(tFileName) '我想这个取文件长度的函数不用我教你怎么写了吧?用LOF就可以返回了。
GetSegBytesByFile tFileName,1,tPSegEnd,tPBytes() '切火腿的前头
GetSegBytesByFile tFileName,tBSegOn,tFileSize,tBBytes() '切火腿的后头
Put #tFN,1,tPBytes() '把第一段火腿放在前头。
Put #tFN,LOF(tFN),tPBytes() '把第二段火腿放在后头。如果有丢失一个字节数据的错误可以实验LOF(tFN)+1,我也懒得去实验到底该不该加一了。
Close #tFN 上面的函数没有测试过,只是给你说明原理。具体的可以运行的程序如果你一定要我帮你写,那就等我zzzZZZ一觉之后吧。熬了一夜游戏,我可困了!