C#:FileStream.Read()不读取文件,但返回0

时间:2009-08-11 16:44:05

标签: c# filestream

我是这样做的:

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();
}

str数组以这些行结束:

  

*****手的历史T5-2847880-18(比赛:S-976-46079)*****
  起手:8月11日星期二18:14

但文件中有更多行。

我已将error.txt上传到sentpace:http://www.sendspace.com/file/5vgjtn 这是完整的控制台输出:the_same_site / file / k05x3a

请帮忙!我在这里真的很无能为力。 提前谢谢!

5 个答案:

答案 0 :(得分:16)

您的代码在以下方面存在一些微妙的错误和问题:

  • 您认为通过调用GetString(b)
  • 填充了整个缓冲区
  • 您假设每个缓冲区都在字符的末尾结束。使用TextReader(例如StreamReader)阅读文字数据,避免此类问题。
  • 如果发生异常(使用using指令)
  • ,您不会关闭文件
  • 您在循环中使用字符串连接:prefer StringBuilder

正如其他人所指出的那样,File.ReadAllLines会避免很多这方面的工作。对于非文件,还有File.ReadAllTextTextReader.ReadToEnd

最后,只需使用Encoding.UTF8而不是创建新实例,除非您确实需要调整一些选项。

答案 1 :(得分:4)

从技术上讲,这不是你问题的答案,但你可以用以下内容替换所有内容:

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

编辑(按照承诺):
在我看来,你不会遗漏一件作品,而是会有最后一部分的副本。您没有从文件中读取完整的1024个字节,但是您将所有1024个字节转换为字符串并附加它。

你的循环应该是这样的:

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

除此之外:乔恩说:)

答案 2 :(得分:2)

为什么不让你的生活更轻松并做到这一点?

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

答案 3 :(得分:0)

您可能会发现简单地使用File.ReadLines()会更加容易。跳过你不关心的行,而不是使用该位置。

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

您还可以使用StreamReader,它允许您在设置其位置后包装流,然后使用ReadLine()方法。

答案 4 :(得分:0)

我知道这很旧了,但是请检查一下:

public void StreamBuffer(Stream sourceStream, Stream destinationStream, int buffer = 4096)
{
    using (var memoryStream = new MemoryStream())
    {
        sourceStream.CopyTo(memoryStream);
        var memoryBuffer = memoryStream.GetBuffer();

        for (int i = 0; i < memoryBuffer.Length;)
        {
            var networkBuffer = new byte[buffer];
            for (int j = 0; j < networkBuffer.Length && i < memoryBuffer.Length; j++)
            {
                networkBuffer[j] = memoryBuffer[i];
                i++;
            }
            destinationStream.Write(networkBuffer, 0, networkBuffer.Length);
        }
    }
}

...并且请记住,内存流非常棒,可以保证从流中获取字节数组以用于其他方式。使用它。