使用stream.Seek可以正确定位读取文件某位置上的数据吗?

时间:2022-04-14 04:50:24
试了很多次,没有一次不是很失望,也找不到问题的解决办法,后来写了下面这个代码做测试,发现使用stream.Seek方法读取到的文件真的和原文件是不同的:前面有一大段是正确的,然后突然跳到后面很远的内容,为什么这么奇怪,哪位高手能帮忙一下,答对会再加分,不胜感激!

long offset = -1;

using (StreamReader reader1 = new StreamReader(path))
{
       using (StreamWriter writer1 = new StreamWriter("D:\\hwind.txt"))
       {
               while (offset < 430561)  {
                      offset++;
                      reader1.BaseStream.Seek(offset, SeekOrigin.Begin);
                      writer1.Write((char)reader1.Read());
               }
       }
}

7 个解决方案

#2


呵呵,楼上误解我的意思了,如果要将一个文本全部地写到另一个文本,那复制也好,大可不必这么麻烦,我的代码主要是想测试 Stream.Seek 能否正确的取到文件数据,因为我需要用 Stream.Seek 或其他什么定位函数来从文件的中间某个位置取得数据(文件太大,我不想遍历文件中不必要的部分)。

#3


问题有所进展,但现在关键是StreamReader如何获得当前文件的准确位置?使用StreamReader.BaseStream.Position不能正确反映当前Read位置的问题,真是失望,哪位高手能帮忙一下啊?

#4


Read读完后,Position就会相应改变的
1楼的代码是顺序读所以说不需要Seek,确保从最开始读就可以了。跳跃式的读才需要Seek的。

你需要判断StreamReader里面的内容是否读到文件末尾了。

            long offset = -1;

            using (StreamReader reader1 = new StreamReader(path))
            {
                using (StreamWriter writer1 = new StreamWriter("D:\\hwind.txt"))
                {
                    while (offset < 430561)
                    {

                            offset++;
                            reader1.BaseStream.Seek(offset, SeekOrigin.Begin);
                            int ch = reader1.Read();
                            if (ch == -1)
                            {
                                break;
                            }
                            writer1.Write((char)ch);

                    }
                }
            }



        //
        // 摘要:
        //     读取输入流中的下一个字符并使该字符的位置提升一个字符。
        //
        // 返回结果:
        //     输入流中表示为 System.Int32 对象的下一个字符。如果不再有可用的字符,则为 -1。
        //
        // 异常:
        //   System.IO.IOException:
        //     发生 I/O 错误。
        public override int Read();

#5


该回复于2011-03-09 09:59:02被版主删除

#6


谢谢楼上同志的热心,但是我当然是必须用Seek才去测试它,你测试过这个程序写出的文件和原文件内容完全相同吗?我测试了,前面是相同的,但是到了几万个字符的时候就突然十来个字符没有了,接下来又一样,隔几万个又有十几个字符不见,看不出不见字符和前后字符有什么特殊之处,真是不可思议的怪事!

            FileStream fs2 = new FileStream("D:\\hwind0.txt", FileMode.Open, FileAccess.Read);
            FileStream fs3 = new FileStream("D:\\hwind.txt", FileMode.Open, FileAccess.Read);
            long iii = 0; long num = 0;
            using (StreamReader reader2 = new StreamReader(fs2))
            {
                using (StreamReader reader3 = new StreamReader(fs3))
                {
                    char chr2 = '\0';
                    char chr3 = '\0';

                    for(int i = 0; i < 430561; i++)
                    {
                        chr2 = (char)reader2.Read();
                        chr3 = (char)reader3.Read();
                        if (chr2 != chr3)
                            num++;
                        else
                            ++iii;
                    }
                }
            }

#7


我怀疑上面是UTF8编码的问题,虽然不至于突然消失了10来个字符。但是还有另一个非常问题,哪位好心的高手能指点一下,StreamReader.Reader()和Stream.ReadByte()除了读出长度可能不一致之外,还有没有可能存在StreamReader.Reader()不能读到的而Stream.ReadByte()能读到的信息?这个问题对我现在非常重要,能告诉我的话不胜感激啊!

#1


#2


呵呵,楼上误解我的意思了,如果要将一个文本全部地写到另一个文本,那复制也好,大可不必这么麻烦,我的代码主要是想测试 Stream.Seek 能否正确的取到文件数据,因为我需要用 Stream.Seek 或其他什么定位函数来从文件的中间某个位置取得数据(文件太大,我不想遍历文件中不必要的部分)。

#3


问题有所进展,但现在关键是StreamReader如何获得当前文件的准确位置?使用StreamReader.BaseStream.Position不能正确反映当前Read位置的问题,真是失望,哪位高手能帮忙一下啊?

#4


Read读完后,Position就会相应改变的
1楼的代码是顺序读所以说不需要Seek,确保从最开始读就可以了。跳跃式的读才需要Seek的。

你需要判断StreamReader里面的内容是否读到文件末尾了。

            long offset = -1;

            using (StreamReader reader1 = new StreamReader(path))
            {
                using (StreamWriter writer1 = new StreamWriter("D:\\hwind.txt"))
                {
                    while (offset < 430561)
                    {

                            offset++;
                            reader1.BaseStream.Seek(offset, SeekOrigin.Begin);
                            int ch = reader1.Read();
                            if (ch == -1)
                            {
                                break;
                            }
                            writer1.Write((char)ch);

                    }
                }
            }



        //
        // 摘要:
        //     读取输入流中的下一个字符并使该字符的位置提升一个字符。
        //
        // 返回结果:
        //     输入流中表示为 System.Int32 对象的下一个字符。如果不再有可用的字符,则为 -1。
        //
        // 异常:
        //   System.IO.IOException:
        //     发生 I/O 错误。
        public override int Read();

#5


该回复于2011-03-09 09:59:02被版主删除

#6


谢谢楼上同志的热心,但是我当然是必须用Seek才去测试它,你测试过这个程序写出的文件和原文件内容完全相同吗?我测试了,前面是相同的,但是到了几万个字符的时候就突然十来个字符没有了,接下来又一样,隔几万个又有十几个字符不见,看不出不见字符和前后字符有什么特殊之处,真是不可思议的怪事!

            FileStream fs2 = new FileStream("D:\\hwind0.txt", FileMode.Open, FileAccess.Read);
            FileStream fs3 = new FileStream("D:\\hwind.txt", FileMode.Open, FileAccess.Read);
            long iii = 0; long num = 0;
            using (StreamReader reader2 = new StreamReader(fs2))
            {
                using (StreamReader reader3 = new StreamReader(fs3))
                {
                    char chr2 = '\0';
                    char chr3 = '\0';

                    for(int i = 0; i < 430561; i++)
                    {
                        chr2 = (char)reader2.Read();
                        chr3 = (char)reader3.Read();
                        if (chr2 != chr3)
                            num++;
                        else
                            ++iii;
                    }
                }
            }

#7


我怀疑上面是UTF8编码的问题,虽然不至于突然消失了10来个字符。但是还有另一个非常问题,哪位好心的高手能指点一下,StreamReader.Reader()和Stream.ReadByte()除了读出长度可能不一致之外,还有没有可能存在StreamReader.Reader()不能读到的而Stream.ReadByte()能读到的信息?这个问题对我现在非常重要,能告诉我的话不胜感激啊!