Text File Insert Append Prepend Replace Delete line
Posted: Fri May 20, 2011 4:27 am
Expanding on this post: http://www.purebasic.fr/english/viewtop ... =12&t=3626 about inserting a line into a text file, below is a procedure for each of Insert, Append, Prepend, Replace and Delete a whole line of text.
First thing to note is that they all work and should be cross-platform
Second thing to note is that they could all be improved/replaced to work faster with large files
Contents of very simple test file "C:\TestFile.txt" (so short that of course the speed is good):
Test Line 1
Test Line 22
Test Line 333
Test Line 4444
Test Line 55555
Test Line 666666
Test Line 7777777
Test Line 88888888
Test Line 999999999
Test Line 01010101010
Test Line 1111111111111
Test Line 1212121212121212
So, the challenge is to improve the speed, but without any API or other dependencies.......
Edit 01: Free Memory; Use WriteStringN
Edit 02: File Fail friendly
Edit03: DeleteLine() replaced with faster code by Bernd
First thing to note is that they all work and should be cross-platform


Contents of very simple test file "C:\TestFile.txt" (so short that of course the speed is good):
Test Line 1
Test Line 22
Test Line 333
Test Line 4444
Test Line 55555
Test Line 666666
Test Line 7777777
Test Line 88888888
Test Line 999999999
Test Line 01010101010
Test Line 1111111111111
Test Line 1212121212121212
Code: Select all
Procedure DeleteLine(iFileID,sFileName.s,iDelLineNum.i)
;------------------------------------------------------
; ***** Fast code by Bernd (infratec), made fail friendly by IdeasVacuum *****
iReturnVal.i = #True
iSize.l = FileSize(sFileName)
iReadLen.l = 0
i.i = 1
n.i = 0
iLength.l = 0
If iSize > 0
If ReadFile(iFileID,sFileName)
*Buffer = AllocateMemory(iSize)
If *Buffer
iReadLen = ReadData(iFileID, *Buffer, iSize)
CloseFile(iFileID)
If(iReadLen = iSize)
While i < iDelLineNum
If PeekA(*Buffer + n) = $0A
i + 1
EndIf
n + 1
Wend
*Dest = *Buffer + n
n = 0
While PeekA(*Dest + n) <> $0A
n + 1
Wend
*Source = *Dest + n + 1
iLength = (*Buffer + iSize) - *Source
MoveMemory(*Source, *Dest, iLength)
iSize - n - 1
If CreateFile(iFileID, sFileName)
WriteData(iFileID, *Buffer, iSize)
CloseFile(iFileID)
Else
MessageRequester("File Issue","File create failed",#PB_MessageRequester_Ok)
iReturnVal = #False
EndIf
Else
MessageRequester("Memory Issue","File read failed",#PB_MessageRequester_Ok)
iReturnVal = #False
EndIf
FreeMemory(*Buffer)
Else
MessageRequester("Memory Issue","Memory allocation failed",#PB_MessageRequester_Ok)
iReturnVal = #False
EndIf
Else
MessageRequester("File Issue","File open failed",#PB_MessageRequester_Ok)
iReturnVal = #False
EndIf
Else
MessageRequester("File Issue","File empty",#PB_MessageRequester_Ok)
iReturnVal = #False
EndIf
ProcedureReturn(iReturnVal)
EndProcedure
Procedure InsertLine(iFileID,sFileName.s,iLine.i,sNewLine.s,iMode.i)
;-------------------------------------------------------------------
NewList sData.s()
iReturnVal = #TRUE
If ReadFile(iFileID,sFileName)
While Eof(iFileID) = 0
AddElement(sData())
sData() = ReadString(iFileID)
Wend
CloseFile(iFileID)
SelectElement(sData(),iLine)
InsertElement(sData())
sData() = sNewLine
If CreateFile(iFileID,sFileName)
FirstElement(sData())
For i = 1 To ListSize(sData())
WriteStringN(iFileID,sData(),iMode)
NextElement(sData())
Next
CloseFile(iFileID)
Else
MessageRequester("File Issue","File create failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
Else
MessageRequester("File Issue","File read failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
FreeList(sData())
ProcedureReturn(iReturnVal)
EndProcedure
Procedure PrependLine(iFileID,sFileName.s,sPrependLine.s,iMode.i)
;----------------------------------------------------------------
iFileLen.l = 0
iReadLen.l = 0
iStrLen.l = 0
iReturnVal = #TRUE
If ReadFile(iFileID,sFileName)
iFileLen = Lof(iFileID)
If(iFileLen > 0)
*MemFile = AllocateMemory(iFileLen)
If *MemFile
iReadLen = ReadData(iFileID,*MemFile,iFileLen)
EndIf
CloseFile(iFileID)
If(iFileLen = iReadLen)
If CreateFile(iFileID,sFileName)
WriteStringN(iFileID,sPrependLine,iMode)
WriteData(iFileID,*MemFile,iFileLen)
CloseFile(iFileID)
Else
MessageRequester("File Issue","File create failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
Else
MessageRequester("Memory Issue","File read failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
Else
MessageRequester("File Issue","File empty",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
Else
MessageRequester("File Issue","File read failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
If *MemFile : FreeMemory(*MemFile) : EndIf
ProcedureReturn(iReturnVal)
EndProcedure
Procedure AppendLine(iFileID,sFileName.s,sAppendLine.s,iMode.i)
;--------------------------------------------------------------
iStrLen.l = 0
iFileLen.l = 0
iReturnVal = #TRUE
If OpenFile(iFileID,sFileName)
iFileLen = Lof(iFileID)
If(iFileLen > 0)
FileSeek(iFileID,iFileLen)
; line to be appended
WriteStringN(iFileID,sAppendLine,iMode)
CloseFile(iFileID)
Else
MessageRequester("File Issue","File empty",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
Else
MessageRequester("File Issue","Open file failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
ProcedureReturn(iReturnVal)
EndProcedure
Procedure ReplaceLine(iFileID,sFileName.s,iRepLineNum.i,sReplacement.s,iMode.i)
;-----------------------------------------------------------------------------
NewList sData.s()
iReturnVal = #TRUE
If ReadFile(iFileID,sFileName)
While Eof(iFileID) = 0
AddElement(sData())
sData() = ReadString(iFileID)
Wend
CloseFile(iFileID)
SelectElement(sData(),(iRepLineNum - 1)) ; -1 because first element number is zero
sData() = sReplacement
If CreateFile(iFileID,sFileName)
FirstElement(sData())
For i = 1 To ListSize(sData())
WriteStringN(iFileID,sData(),iMode)
NextElement(sData())
Next
CloseFile(iFileID)
Else
MessageRequester("File Issue","File create failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
Else
MessageRequester("File Issue","File read failed",#PB_MessageRequester_Ok)
iReturnVal = #FALSE
EndIf
FreeList(sData())
ProcedureReturn(iReturnVal)
EndProcedure
iReturn.i = 0
;### Test: replace line 5 ###
iReturn = ReplaceLine(0,"C:\TestFile.txt",5,"Replacement Text",iMode.i)
;### Test: insert line after line 8 ###
iReturn = InsertLine(0,"C:\TestFile.txt",8,"Inserted Line",#PB_Ascii)
;### Test: delete line 3 ###
iReturn = DeleteLine(0,"C:\TestFile.txt",3)
;### Test: append a line ###
iReturn = AppendLine(0,"C:\TestFile.txt","Appended Line",#PB_Ascii)
;### Test: Prepend string ###
iReturn = PrependLine(0,"C:\TestFile.txt","Prepended Line",#PB_Ascii)
End
Edit 01: Free Memory; Use WriteStringN
Edit 02: File Fail friendly
Edit03: DeleteLine() replaced with faster code by Bernd