@@ -24,10 +24,6 @@ namespace SocialExplorer.IO.FastDBF
2424 /// This class represents a DBF file. You can create new, open, update and save DBF files using this class and supporting classes.
2525 /// Also, this class supports reading/writing from/to an internet forward only type of stream!
2626 /// </summary>
27- /// <remarks>
28- /// TODO: add end of file byte '0x1A' !!!
29- /// We don't relly on that byte at all, and everything works with or without that byte, but it should be there by spec.
30- /// </remarks>
3127 public class DbfFile
3228 {
3329
@@ -42,6 +38,10 @@ public class DbfFile
4238 /// </summary>
4339 protected bool _headerWritten = false ;
4440
41+ /// <summary>
42+ /// flag that indicates whether a footer update is required
43+ /// </summary>
44+ protected bool _footerUpdateNeeded = false ;
4545
4646 /// <summary>
4747 /// Streams to read and write to the DBF file.
@@ -204,13 +204,19 @@ public void Close()
204204 if ( _header . IsDirty )
205205 WriteHeader ( ) ;
206206
207-
207+ //try to update the footer if the file has been udpated
208+ //------------------------------------------
209+ if ( _footerUpdateNeeded )
210+ WriteFooter ( ) ;
208211
209212 //Empty header...
210213 //--------------------------------
211214 _header = new DbfHeader ( encoding ) ;
212215 _headerWritten = false ;
213216
217+ //Clear the footer required flag
218+ //------------------------------------------
219+ _footerUpdateNeeded = false ;
214220
215221 //reset current record index
216222 //--------------------------------
@@ -548,6 +554,7 @@ public void Update(DbfRecord orec)
548554 //write
549555 orec . Write ( _dbfFile ) ;
550556
557+ _footerUpdateNeeded = true ;
551558
552559 }
553560
@@ -569,6 +576,7 @@ public bool WriteHeader()
569576 _dbfFileWriter . Seek ( 0 , SeekOrigin . Begin ) ;
570577 _header . Write ( _dbfFileWriter ) ;
571578 _headerWritten = true ;
579+ _footerUpdateNeeded = true ;
572580 return true ;
573581 }
574582 else
@@ -578,15 +586,53 @@ public bool WriteHeader()
578586 _header . Write ( _dbfFileWriter ) ;
579587
580588 _headerWritten = true ;
581-
589+ _footerUpdateNeeded = true ;
582590 }
583591 }
584592
585593 return false ;
586594
587595 }
588596
597+ public bool WriteFooter ( )
598+ {
599+ // return false if it's not possible to write.
600+ if ( _dbfFileWriter == null )
601+ {
602+ return false ;
603+ }
604+
605+
606+ //if stream can not seek, then just write it out and that's it.
607+ if ( ! _dbfFileWriter . BaseStream . CanSeek )
608+ {
609+ _dbfFileWriter . Write ( ( byte ) 0x1A ) ;
610+ return true ;
611+ }
612+
613+ var streamLength = _dbfFileWriter . BaseStream . Length ;
614+ var expectedLength = Header . HeaderLength + Header . RecordCount * Header . RecordLength + 1 ;
615+
616+ // If the length of the stream is the same as the expected length, seek ready to re-write the last byte.
617+ if ( streamLength == expectedLength )
618+ {
619+ _dbfFileWriter . BaseStream . Seek ( - 1 , SeekOrigin . End ) ;
620+ }
621+ // If the length of the stream is one less than expected length, seek ready to append the last byte.
622+ else if ( streamLength == expectedLength - 1 )
623+ {
624+ _dbfFileWriter . BaseStream . Seek ( 0 , SeekOrigin . End ) ;
625+ }
626+ // Otherwise, something isn't right. return false.
627+ else
628+ {
629+ return false ;
630+ }
589631
632+ // Write the last byte and return true
633+ _dbfFileWriter . Write ( ( byte ) 0x1A ) ;
634+ return true ;
635+ }
590636
591637 /// <summary>
592638 /// Access DBF header with information on columns. Use this object for faster access to header.
0 commit comments