C#读文件为什么结束不了啦,大家帮忙看看代码

大_爱 2013-06-27 10:12:49


String path = @"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv";

//Open the stream and read it back.
FileStream fs = File.OpenRead(path);
FileStream fo = File.OpenWrite(@"E://Ju-on.2000.2in1.DVDRip-AVC.mkv");
byte[] b = new byte[1024 * 1024];
while (fs.Read(b,0,b.Length) >= 0)
{
fo.Write(b,0,b.Length);
fo.Flush();
}
fo.Close();
fs.Close();



这是按照帮助文档上写的读写文件,刻个文件一共2G,可是一直结束不了,会多出几个G出来。

byte写1024的话就没有问题,些1024 * 1024 就有问题了。

...全文
342 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
敌敌畏耶 2013-06-28
  • 打赏
  • 举报
回复
引用 5 楼 beefcattlexiaoyang 的回复:
[quote=引用 1 楼 Kim_Du 的回复:] 肯定会一直写下去啊,你写1024个和1024*1024个能一样吗?
byte[] 最大能多大啊? 在线等。。。。[/quote] byte 是0到255吧····
  • 打赏
  • 举报
回复
为什么不用File.Copy,多好,别人一看就知道那干嘛用的
Regan-lin 2013-06-27
  • 打赏
  • 举报
回复
应该是读写时候的长度精确出问题了吧,不过也没有理由2G的东西能多出几G来啊
Regan-lin 2013-06-27
  • 打赏
  • 举报
回复
引用 5 楼 beefcattlexiaoyang 的回复:
[quote=引用 1 楼 Kim_Du 的回复:] 肯定会一直写下去啊,你写1024个和1024*1024个能一样吗?
byte[] 最大能多大啊? 在线等。。。。[/quote] 肯定比你这个1024*1024这个大!
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 13 楼 Kim_Du 的回复:
按照你之前的那样不行吗?
嗯,发送到网路端都是一样的代码,都会结束不了!
Kim_Du 2013-06-27
  • 打赏
  • 举报
回复
按照你之前的那样不行吗?
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 11 楼 Kim_Du 的回复:
我试了一下,你将等号去掉,就好了,虽然会出现你上面说的那个问题,但是多出来的大小不会大于你定义的一个byte的大小的,因为只有在最后读取的一个byte里面才会出现内容不足的情况
我把等号去掉了,读写文件也没问题,文件比之前的大一点,但是网路发送会变大。


            FileStream fs = File.OpenRead(@"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv");
            Byte[] sendByte = new Byte[1024 * 1024 * 10];
            //Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            
            while (fs.Read(sendByte, 0, sendByte.Length) > 0)
            {
                clientSocket.Send(sendByte);
            }
            fs.Close();
            

Kim_Du 2013-06-27
  • 打赏
  • 举报
回复
我试了一下,你将等号去掉,就好了,虽然会出现你上面说的那个问题,但是多出来的大小不会大于你定义的一个byte的大小的,因为只有在最后读取的一个byte里面才会出现内容不足的情况
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 8 楼 tcmakebest 的回复:
这里有两个错误,另一个错误你还不容易发现 1 fs.Read 如果遇到文件结束,会返回 0 ,但你并不退出循环,这就是问题 2 fo.Write 的长度你写错了,应该用 fs.Read 返回的长度,这样会导致文件比原来的长,多出来的部分内容是最后第二次读取的,导致文件长度变成数组长度的整数倍。
我觉得第一个 问题是不存在的,while()不满足条件的时候自己就退出了。 第二个问题存在,我还不知道怎么修改,我看MSDN中也是这么写的。 我就照抄过来了。
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 7 楼 Kim_Du 的回复:
你将if里面的改成大于0试一下,我记得好像读到末尾的时候就返回值为0. 但是你说1024的时候就好着。。。
嗯,byte 里面写1024 就没有问题,写大了就会一直读。 原来我是写的>0 ,也有问题,后来我修改成>=0 ,一样的效果。
tcmakebest 2013-06-27
  • 打赏
  • 举报
回复
这里有两个错误,另一个错误你还不容易发现 1 fs.Read 如果遇到文件结束,会返回 0 ,但你并不退出循环,这就是问题 2 fo.Write 的长度你写错了,应该用 fs.Read 返回的长度,这样会导致文件比原来的长,多出来的部分内容是最后第二次读取的,导致文件长度变成数组长度的整数倍。
Kim_Du 2013-06-27
  • 打赏
  • 举报
回复
你将if里面的改成大于0试一下,我记得好像读到末尾的时候就返回值为0. 但是你说1024的时候就好着。。。
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 4 楼 Kim_Du 的回复:
不好意思看错了。。。
我也不明白为什么会一直读写下去。。。
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 1 楼 Kim_Du 的回复:
肯定会一直写下去啊,你写1024个和1024*1024个能一样吗?
byte[] 最大能多大啊? 在线等。。。。
Kim_Du 2013-06-27
  • 打赏
  • 举报
回复
不好意思看错了。。。
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 1 楼 Kim_Du 的回复:
肯定会一直写下去啊,你写1024个和1024*1024个能一样吗?
?? 不懂,为什么不一样?
Kim_Du 2013-06-27
  • 打赏
  • 举报
回复
肯定会一直写下去啊,你写1024个和1024*1024个能一样吗?
大_爱 2013-06-27
  • 打赏
  • 举报
回复
引用 31 楼 wyd1520 的回复:
[quote=引用 楼主 beefcattlexiaoyang 的回复:]


String path = @"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv";

            //Open the stream and read it back.
            FileStream fs = File.OpenRead(path);
            FileStream fo = File.OpenWrite(@"E://Ju-on.2000.2in1.DVDRip-AVC.mkv");
            byte[] b = new byte[1024 * 1024];
            while (fs.Read(b,0,b.Length) >= 0) 
            {
                fo.Write(b,0,b.Length);
                fo.Flush();
            }
            fo.Close();
            fs.Close();

这是按照帮助文档上写的读写文件,刻个文件一共2G,可是一直结束不了,会多出几个G出来。 byte写1024的话就没有问题,些1024 * 1024 就有问题了。
你是为了传输文件?那要做分块。。写个文件分块类。。看你结贴率高,就给你一个我项目上用的文件传输分块的类,你一下就明白了。


public class FileReader
    {
        
        private long _partCount;
        private long _length;
        private int _partSize = 4096 * 4;//每个块容量
        private string _md5;
        private object _tag;
        private byte[] _partBuffer;
        private int readPartIndex;
        private string _filePath;
        private DateTime _LastReadTime;
        private string _fileName;

        public DateTime LastReadTime { get { return _LastReadTime; } }


        public bool IsTimeout
        {
            get
            {
                return (DateTime.Now - _LastReadTime).TotalMinutes > 5;
            }
        }

        public string Key { get; set; }

        /// <summary>
        /// 块数量
        /// </summary>
        public long PartCount
        {
            get { return _partCount; }
        }

        /// <summary>
        /// 文件长度
        /// </summary>
        public long Length
        {
            get { return _length; }
        }

        /// <summary>
        /// 每块容量
        /// </summary>
        public int PartSize
        {
            get { return _partSize; }
        }


        /// <summary>
        /// 文件路径
        /// </summary>
        public string FilePath
        {
            get { return _filePath; }
        }

        /// <summary>
        /// 文件名
        /// </summary>
        public string FileName
        {
            get { return _fileName; }
        }

        /// <summary>
        /// MD5码
        /// </summary>
        public string MD5
        {
            get { return _md5; }
        }


        public object Tag
        {
            get
            {
                return _tag;
            }
            set
            {
                _tag = value;
            }
        }


        public FileReader(string filePath)
        {

            this._filePath = filePath;
            this._fileName = Path.GetFileName(filePath);
            this._partBuffer = new byte[_partSize];
            InitReader();
        }

        public FileReader(string filePath, int partSize)
        {
            this._filePath = filePath;
            this._fileName = Path.GetFileName(filePath);
            this._partSize = partSize;
            this._partBuffer = new byte[_partSize];
            InitReader();
        }


        private void InitReader()
        {
            _LastReadTime = DateTime.Now;
            using (FileStream _fileStream = CreateReader())
            {
                _length = _fileStream.Length;
                _partCount = _length / _partSize;
                if (_length % _partSize != 0)
                {
                    _partCount++;
                }
                _md5 = MD5Helper.CretaeMD5(_fileStream);
                _fileStream.Close();
            }
        }

        private FileStream CreateReader()
        {
            FileStream fileStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read, _partSize * 10, false);
            return fileStream;
        }



        public byte[] Read(long index)
        {
            _LastReadTime = DateTime.Now;

            if (index >= _partCount || index < 0)
                return null;

            int size = _partSize;

            if (_length - _partSize * index < _partSize)
            {
                size = (int)(_length - _partSize * index);
            }

            using (FileStream _fileStream = CreateReader())
            {
                _fileStream.Position = index * _partSize;
                int len = _fileStream.Read(this._partBuffer, 0, size);
                byte[] buffer = new byte[len];
                Buffer.BlockCopy(_partBuffer, 0, buffer, 0, len);
                _fileStream.Close();
                return buffer;
            }
        }



    }


[/quote] 多谢!我去试试! 感谢大家。先结贴了,如果我解决这个问题,我会把答案写在这里的。!
本拉灯 2013-06-27
  • 打赏
  • 举报
回复
引用 楼主 beefcattlexiaoyang 的回复:


String path = @"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv";

            //Open the stream and read it back.
            FileStream fs = File.OpenRead(path);
            FileStream fo = File.OpenWrite(@"E://Ju-on.2000.2in1.DVDRip-AVC.mkv");
            byte[] b = new byte[1024 * 1024];
            while (fs.Read(b,0,b.Length) >= 0) 
            {
                fo.Write(b,0,b.Length);
                fo.Flush();
            }
            fo.Close();
            fs.Close();

这是按照帮助文档上写的读写文件,刻个文件一共2G,可是一直结束不了,会多出几个G出来。 byte写1024的话就没有问题,些1024 * 1024 就有问题了。
你是为了传输文件?那要做分块。。写个文件分块类。。看你结贴率高,就给你一个我项目上用的文件传输分块的类,你一下就明白了。


public class FileReader
    {
        
        private long _partCount;
        private long _length;
        private int _partSize = 4096 * 4;//每个块容量
        private string _md5;
        private object _tag;
        private byte[] _partBuffer;
        private int readPartIndex;
        private string _filePath;
        private DateTime _LastReadTime;
        private string _fileName;

        public DateTime LastReadTime { get { return _LastReadTime; } }


        public bool IsTimeout
        {
            get
            {
                return (DateTime.Now - _LastReadTime).TotalMinutes > 5;
            }
        }

        public string Key { get; set; }

        /// <summary>
        /// 块数量
        /// </summary>
        public long PartCount
        {
            get { return _partCount; }
        }

        /// <summary>
        /// 文件长度
        /// </summary>
        public long Length
        {
            get { return _length; }
        }

        /// <summary>
        /// 每块容量
        /// </summary>
        public int PartSize
        {
            get { return _partSize; }
        }


        /// <summary>
        /// 文件路径
        /// </summary>
        public string FilePath
        {
            get { return _filePath; }
        }

        /// <summary>
        /// 文件名
        /// </summary>
        public string FileName
        {
            get { return _fileName; }
        }

        /// <summary>
        /// MD5码
        /// </summary>
        public string MD5
        {
            get { return _md5; }
        }


        public object Tag
        {
            get
            {
                return _tag;
            }
            set
            {
                _tag = value;
            }
        }


        public FileReader(string filePath)
        {

            this._filePath = filePath;
            this._fileName = Path.GetFileName(filePath);
            this._partBuffer = new byte[_partSize];
            InitReader();
        }

        public FileReader(string filePath, int partSize)
        {
            this._filePath = filePath;
            this._fileName = Path.GetFileName(filePath);
            this._partSize = partSize;
            this._partBuffer = new byte[_partSize];
            InitReader();
        }


        private void InitReader()
        {
            _LastReadTime = DateTime.Now;
            using (FileStream _fileStream = CreateReader())
            {
                _length = _fileStream.Length;
                _partCount = _length / _partSize;
                if (_length % _partSize != 0)
                {
                    _partCount++;
                }
                _md5 = MD5Helper.CretaeMD5(_fileStream);
                _fileStream.Close();
            }
        }

        private FileStream CreateReader()
        {
            FileStream fileStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read, _partSize * 10, false);
            return fileStream;
        }



        public byte[] Read(long index)
        {
            _LastReadTime = DateTime.Now;

            if (index >= _partCount || index < 0)
                return null;

            int size = _partSize;

            if (_length - _partSize * index < _partSize)
            {
                size = (int)(_length - _partSize * index);
            }

            using (FileStream _fileStream = CreateReader())
            {
                _fileStream.Position = index * _partSize;
                int len = _fileStream.Read(this._partBuffer, 0, size);
                byte[] buffer = new byte[len];
                Buffer.BlockCopy(_partBuffer, 0, buffer, 0, len);
                _fileStream.Close();
                return buffer;
            }
        }



    }


大_爱 2013-06-27
  • 打赏
  • 举报
回复
感谢大家的回答,我想问题还是出在byte[] 上。
引用 24 楼 dongxinxi 的回复:
如果想一次读完,有简单方法 var fs = System.IO.File.OpenRead() using(var ms = new MemoryStream(fs)) byte[] datas = ms.ToArray(); 不过大文件一般都是分块发送
我不想一次传输完成,因为文件的大小是不固定的。
引用 26 楼 fittec 的回复:
while (fs.Read(b,0,b.Length) >= 0) { fo.Write(b,0,b.Length); fo.Flush(); } 问题出在这里!
这个>=我已经修改了,读写本地的文件没有问题,发送到网路就有问题了。
引用 27 楼 wyd1520 的回复:
[quote=引用 楼主 beefcattlexiaoyang 的回复:]


String path = @"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv";

            //Open the stream and read it back.
            FileStream fs = File.OpenRead(path);
            FileStream fo = File.OpenWrite(@"E://Ju-on.2000.2in1.DVDRip-AVC.mkv");
            byte[] b = new byte[1024 * 1024];
            while (fs.Read(b,0,b.Length) >= 0) 
            {
                fo.Write(b,0,b.Length);
                fo.Flush();
            }
            fo.Close();
            fs.Close();

这是按照帮助文档上写的读写文件,刻个文件一共2G,可是一直结束不了,会多出几个G出来。 byte写1024的话就没有问题,些1024 * 1024 就有问题了。



String path = @"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv";
 
            //Open the stream and read it back.
            FileStream fs = File.OpenRead(path);
            FileStream fo = File.OpenWrite(@"E://Ju-on.2000.2in1.DVDRip-AVC.mkv");
            byte[] b = new byte[1024 * 1024];
            while (fs.Read(b,0,b.Length) >= 0) <-问题出在这知道没
            {
                fo.Write(b,0,b.Length);
                fo.Flush();
            }
            fo.Close();
            fs.Close();

           //改成这样
         String path = @"D://TDDOWNLOAD//Ju-on.2000.2in1.DVDRip-AVC.mkv";
            //Open the stream and read it back.
            FileStream fs = File.OpenRead(path);
            FileStream fo = File.OpenWrite(@"E://Ju-on.2000.2in1.DVDRip-AVC.mkv");
            byte[] b = new byte[1024 * 1024];
            int reLen=0;
            while ((reLen=fs.Read(b,0,b.Length))>= 0)  //<--这里要这样
            {
                fo.Write(b,0,reLen); 《-这里要这样
                fo.Flush();
            }
            fo.Close();
            fs.Close();

[/quote] 好的,我试试。
引用 28 楼 fittec 的回复:
byte[] b = new byte[1024 * 1024]; 红色字建议改为何4096或8192 while (fs.Read(b,0,b.Length) >4096或8192)
这个应该不影响的,还是感谢的回答。
加载更多回复(11)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧