多线程传输文件辅助类

基类

 

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.IO;
namespace  SocketServer
{
    
public delegate void FileEvent(FileBase f);
    
public class FileBase
    
{
        
protected FileStream _stream;       //文件流
        protected string _fileInfo;         //文件说明,最长204字节
        protected string _fileName;         //文件名最长255字节
        protected long _fileSize;           //文件大小
        protected int _allBagNums;          //总包数
        protected int _bagSize;             //包大小
        protected int _readLen;             //实际每包可发送的有效字节
        protected int _currentBag;          //正在接收或发送的包数
        protected byte[] _fileMark;         //文件标识四字节,产生时为随机数
        protected bool _checkout;           //接收时是否进行检查
        public const byte BagMark = 4;      //包标识
        public const int _firstBagLen = 8192;//第一包的长度
        protected const int _checkLen = 16//包尾检查位的长度

        
属性

        
public FileBase()
        
{
            _fileInfo 
= "";
            _fileMark 
= new byte[4];
            _currentBag 
= -1;
            _checkout 
= true;
        }

        
~FileBase()
        
{
             
if (_stream != null)
            
{
                _stream.Close();
            }

            _fileInfo 
= null;
            _fileName 
= null;
        }

        
public virtual void Close()
        
{
            
if (_stream != null)
            
{
                _stream.Close();
            }

        }

        
/// <summary>
        
/// 得到每一包的前8个字节
        
/// 第一字节为包标识,后三字节为包序号.最后四个字节为文件标识
        
/// </summary>
        
/// <param name="bagNum">包序号</param>
        
/// <returns>byte[4]</returns>

        protected byte[] getBagHead(int bagSequence)
        
{
            
byte[] baghead = new byte[8];
            baghead[
0= BagMark;
            
for (byte i = 1; i < 4; i++)
            
{
                baghead[i] 
= (byte)(bagSequence & 0xFF);
                bagSequence 
= bagSequence >> 8;
            }

            Array.Copy(_fileMark, 
0, baghead, 44);
            
return baghead;
        }


        
/// <summary>
        
/// 文件的附加信息(第一包)
        
/// </summary>
        
/// <returns>byte[]</returns>

        protected byte[] GetBaseInfo()
        
{
            
byte[] binBaghead = getBagHead(0);
            
byte[] binFileSize = Int2Bin(_fileSize, 8);                 //文件大小
            byte[] binAllBagNums = Int2Bin(_allBagNums, 4);             //总包数
            byte[] binBagSize = Int2Bin(_bagSize, 4);                   //包大小
            byte[] binReadLen = Int2Bin(_readLen, 4);                   //实际每包发送的有效字节
            byte[] binFileName = Encoding.Default.GetBytes(_fileName);  //文件名最长255字节
            byte[] binFileInfo = Encoding.Default.GetBytes(_fileInfo);  //文件说明,最长204字节

            
byte[] firstBag = new byte[_firstBagLen];

            
long desIndex = 0;
            Array.Copy(binBaghead, 
0, firstBag, desIndex, binBaghead.Length);
            desIndex 
+= binBaghead.Length;

            Array.Copy(binFileSize, 
0, firstBag, desIndex, 8);
            desIndex 
+= 8;
            Array.Copy(binAllBagNums, 
0, firstBag, desIndex, 4);
            desIndex 
+= 4;
            Array.Copy(binBagSize, 
0, firstBag, desIndex, 4);
            desIndex 
+= 4;
            Array.Copy(binReadLen, 
0, firstBag, desIndex, 4);
            desIndex 
+= 4;
            Array.Copy(binFileName, 
0, firstBag, desIndex, Math.Min(255, binFileName.Length));
            desIndex 
+= 255;
            
if (!_checkout) firstBag[desIndex] = 1;                     //是否启用检查,为1是不检查.其它则检查
            desIndex += 1;
            Array.Copy(binFileInfo, 
0, firstBag, desIndex, Math.Min(196, binFileInfo.Length));
            desIndex 
+= 196;
            
return firstBag;
        }

        
/// <summary>
        
/// 得到文件信息
        
/// </summary>
        
/// <param name="firstBag">第一包数据(包头加+附加信息,最少512字节)</param>
        
/// <returns>无错误,返回4(等于BagMark)</returns>

        virtual protected int SetBaseInfo(byte[] firstBag)
        
{
            
byte[] baghead = new byte[4];
            
byte[] binFileSize = new byte[8];
            
byte[] binAllBagNums = new byte[4];
            
byte[] binBagSize = new byte[4];
            
byte[] binReadLen = new byte[4];
            
byte[] binFileName = new byte[256];
            
byte[] binFileInfo = new byte[196];
            
long sourceIndex = 0;
            Array.Copy(firstBag, sourceIndex, baghead, 
04);
            sourceIndex 
+= 4;
            Array.Copy(firstBag, sourceIndex, _fileMark, 
04);
            sourceIndex 
+= 4;
            Array.Copy(firstBag, sourceIndex, binFileSize, 
08);
            sourceIndex 
+= 8;
            Array.Copy(firstBag, sourceIndex, binAllBagNums, 
04);
            sourceIndex 
+= 4;
            Array.Copy(firstBag, sourceIndex, binBagSize, 
04);
            sourceIndex 
+= 4;
            Array.Copy(firstBag, sourceIndex, binReadLen, 
04);
            sourceIndex 
+= 4;
            Array.Copy(firstBag, sourceIndex, binFileName, 
0255);
            sourceIndex 
+= 255;
            
if (firstBag[sourceIndex] == 1{ _checkout = false; }
            sourceIndex 
+= 1;
            Array.Copy(firstBag, sourceIndex, binFileInfo, 
0196);
            sourceIndex 
+= 196;
            _fileSize 
= Bin2Int(binFileSize);
            _allBagNums 
= (int)Bin2Int(binAllBagNums);
            _bagSize 
= (int)Bin2Int(binBagSize);
            _readLen 
= (int)Bin2Int(binReadLen);
            _fileName 
= Encoding.Default.GetString(binFileName).Trim('');
            _fileInfo 
= Encoding.Default.GetString(binFileInfo).Trim('');
            
return ReadBagSequence(baghead) + firstBag[0];// +Bin2Int(_fileMark));
        }


        
/// <summary>
        
/// 得到包序号
        
/// </summary>
        
/// <param name="baghead">包头(最少4字节)</param>
        
/// <returns>包序号</returns>

        public static int ReadBagSequence(byte[] baghead)
        
{
            
int bagSequence = 0;
            
for (byte i = 1; i < 4; i++)
            
{
                bagSequence 
+= baghead[i] << ((i - 1<< 3);
            }

            
return bagSequence;
        }


        
/// <summary>
        
/// 将Int转换为Byte[4]
        
/// </summary>

        public static byte[] Int2Bin(long intNum, int length)
        
{
            
byte[] byteNew = new byte[length];
            
for (byte i = 0; i < length; i++)
            
{
                byteNew[i] 
= (byte)(intNum & 0xFF);
                intNum 
= intNum >> 8;
            }

            
return byteNew;
        }


        
/// <summary>
        
/// 将byte转换为Int
        
/// </summary>
        
/// <param name="bin"></param>
        
/// <returns></returns>

        public static long Bin2Int(byte[] bin)
        
{
            
long values = 0;
            
for (byte i = 0; i < bin.Length; i++)
            
{
                values 
+= ((long)bin[i]) << (i << 3);
            }

            
return values;
        }

    }

}

 

发送文件类

 

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.IO;

namespace  SocketServer
{
    
/// <summary>
    
/// 发送文件辅助类
    
/// </summary>

    public class FileSend:FileBase
    
{
        
构造函数

        
/// <summary>
        
/// 读取包数据
        
/// </summary>
        
/// <returns></returns>

        public byte[] Read()
        
{
            _currentBag
++;
            
byte[] bag = new byte[_bagSize];
            
byte[] baghead = getBagHead(_currentBag);
            Array.Copy(baghead, 
0, bag, 08);
            
if (_currentBag < _allBagNums)
            
{                
                _stream.Read(bag, 
8, _readLen);
                
return bag;
            }

            
else
            
{
                _currentBag 
= -1;
                
return new byte[] { };
            }

        }


        
/// <summary>
        
/// 读取文件信息
        
/// </summary>
        
/// <returns></returns>

        public byte[] ReadBase()
        
{
            _currentBag 
= 0;
            _stream.Position 
= 0;
            
return GetBaseInfo();
        }


        
/// <summary>
        
/// 根据包序号读取包数据
        
/// </summary>
        
/// <param name="bagSequence">包序号(从第1包数据开始)</param>
        
/// <returns>byte[]</returns>

        public byte[] GetBags(int bagSequence)
        
{
            
byte[] bag = new byte[_bagSize];
            
byte[] baghead = getBagHead(bagSequence);
            Array.Copy(baghead, 
0, bag, 08);
            
int readLen = 0;
            
if (bagSequence == 0)
            
{
                
return ReadBase();
            }

            
else if (bagSequence < _allBagNums)
            
{
                
long position = (bagSequence - 1* _readLen;
                
lock (_stream)
                
{
                    
long sp = _stream.Position;
                    
if (_stream.Position != position)
                    
{
                        _stream.Position 
= position;
                    }

                    readLen 
= _stream.Read(bag, 8, _readLen);
                    _stream.Position 
= sp;
                }

                
return bag;
            }

            
return new byte[] { };
        }

    }

}

接收文件类

 

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.IO;

namespace  SocketServer
{
    
public class FileRece : FileBase
    
{
        
/// <summary>
        
/// 接收完文件事件
        
/// </summary>

        public event FileEvent ReceivedFile;
        
string _filePath;
        
构造函数
        
/// <summary>
        
/// 创建文件流
        
/// </summary>

        private void creatFile()
        
{
            
string fileFullPaht = _filePath + @"" + _fileName;
            
while (File.Exists(fileFullPaht))
            
{
                fileFullPaht 
+= DateTime.Now.ToFileTime().ToString();
            }

            _stream 
= File.Create(fileFullPaht);
        }


        
/// <summary>
        
/// 初始化
        
/// </summary>
        
/// <param name="firstBag">接收到的第一包数据</param>
        
/// <returns></returns>

        public  int Initialize(byte[] firstBag)
        
{
            
int result = SetBaseInfo(firstBag);
            creatFile();
            _currentBag 
= 0;
            
return result;
        }


        
/// <summary>
        
/// 写数据
        
/// </summary>
        
/// <param name="bin"></param>

        public void Write(byte[] bin)
        
{
            _currentBag
++;
            
long count = _fileSize -(_stream.Length + _readLen);
            
if (count > 0)
            
{
                _stream.Write(bin, 
8, _readLen);
            }

            
else
            
{
                _stream.Write(bin, 
8, (int)(_readLen+count));
                _stream.Close();
                
if (ReceivedFile != null) ReceivedFile(this);
            }

        }

    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值