C #: FileStream.Read () does not read the file to the end, but returns 0

Here is how I do it:

static void Main(string[] args) { string FileName = "c:\\error.txt"; long FilePosition = 137647; FileStream fr = new FileStream(FileName, FileMode.Open); byte[] b = new byte[1024]; string data = string.Empty; fr.Seek(FilePosition, SeekOrigin.Begin); UTF8Encoding encoding = new UTF8Encoding(); while (fr.Read(b, 0, b.Length) > 0) { data += encoding.GetString(b); } fr.Close(); string[] str = data.Split(new string[] { "\r\n" }, StringSplitOptions.None); foreach (string s in str) { Console.WriteLine(s); } Console.ReadKey(); } 

String str ends with the following lines:

***** Hand history T5-2847880-18 (TOURNAMENT: S-976-46079) *****
Start: Tue Aug 11 18:14

but there are more lines in the file.

I uploaded error.txt to sendpace: http://www.sendspace.com/file/5vgjtn And here is the full console output: the_same_site / file / k05x3a

Please, help! I am really clueless here. Thanks in advance!

+4
source share
4 answers

There are some subtle errors and problems in your code in:

  • You assume that the entire buffer was filled with a call to GetString(b)
  • You assume that each buffer ends at the end of a character. Use a TextReader (e.g. StreamReader ) to read text data, avoiding such problems.
  • You do not close the file if an exception occurs (use the using directive)
  • You use string concatenation in a loop: prefer StringBuilder

As others have noted, File.ReadAllLines will avoid this work. There are also File.ReadAllText and TextReader.ReadToEnd for non-files.

Finally, just use Encoding.UTF8 instead of creating a new instance if you really don't need to configure some parameters.

+15
source

Not technically the answer to your question, but you can replace all of this:

 string[] str = File.ReadAllLines("c:\\error.txt"); 

Edit (as promised):
It seems to me that instead of skipping a piece, you will have a duplicate of the last part. You do not read the full 1024 bytes from the file, but you turn all 1024 bytes into a string and add it.

Instead, your loop should look like this:

 int bytesRead; while ((bytesRead = fr.Read(b, 0, b.Length)) > 0) { data += encoding.GetString(b, 0, bytesRead); } 

Also: what John said :)

+4
source

Why don't you make your life easier and do it?

 string[] str = System.IO.File.ReadAllLines("c:\\error.txt"); 
+2
source

It may be easier for you to just use File.ReadLines (). Skip lines that you don't need, instead of using a position.

 int counter = 0; foreach (string s in File.ReadAllLines(FileName)) { ++counter; if (counter > 50?) { Console.WriteLine(s); } } 

You can also use StreamReader, which allows you to wrap the stream after setting its position, and then use the ReadLine () method.

0
source

All Articles