c# - Remove last x lines from a streamreader -
i need read in last x lines file streamreader in c#. best way this?
many thanks!
if it's large file, possible seek end of file, , examine bytes in reverse '\n' character? aware \n , \r\n exists. whipped following code , tested on trivial file. can try testing on files have? know solution looks long, think you'll find it's faster reading beginning , rewriting whole file.
public static void truncate(string file, int lines) { using (filestream fs = file.open(file, filemode.openorcreate, fileaccess.readwrite, fileshare.none)) { fs.position = fs.length; // \n \r\n (both uses \n lines) const int buffer_size = 2048; // start @ end until # lines have been encountered, record position, truncate file long currentposition = fs.position; int linesprocessed = 0; byte[] buffer = new byte[buffer_size]; while (linesprocessed < linestotruncate && currentposition > 0) { int bytesread = fillbuffer(buffer, fs); // have buffer containing later contents of file (int = bytesread - 1; >= 0; i--) { currentposition--; if (buffer[i] == '\n') { linesprocessed++; if (linesprocessed == linestotruncate) break; } } } // truncate file fs.setlength(currentposition); } } private static int fillbuffer(byte[] buffer, filestream fs) { if (fs.position == 0) return 0; int bytesread = 0; int currentbyteoffset = 0; // calculate how many bytes of buffer can filled (remember we're going in reverse) long expectedbytestoread = (fs.position < buffer.length) ? fs.position : buffer.length; fs.position -= expectedbytestoread; while (bytesread < expectedbytestoread) { bytesread += fs.read(buffer, currentbyteoffset, buffer.length - bytesread); currentbyteoffset += bytesread; } // have reset position again because moved reader forward; fs.position -= bytesread; return bytesread; }
since planning on deleting end of file, seems wasteful rewrite everything, if it's large file , small n. of course, 1 can make argument if wanted eliminate lines, going beginning end more efficient.
Comments
Post a Comment