zoukankan      html  css  js  c++  java
  • DFS批量上传文件客户端代码(net版本)

          昨天完成了dfs批量上传文件的服务器端程序,再第一时间就拿出来共享了。当然了,程序比较乱,那是因为我调试的一些信息都留在里面了,是原汁原味的东西,包括一些注释什么的都没有删除,我认为这些东西应该能起到让人更快理解程序的作用,所以就全部放出来了。当然了也有可能注释的错的,大家见谅啊。

          今天完成了客户端程序,因为我主要是做net开发的,所以在dfs没有net客户端的情况下就自己按照我们的业务自己写了一个客户端,今天先把net的批上传文件代码拿出来,也是原汁原味的,没有经过调试的时候任何更改的。

      /// <summary>
            /// 批量上传文件.
            /// </summary>
            /// <param name="groupName">Name of the group.</param>
            /// <param name="filesCount">The files count.</param>
            /// <param name="localFileName">Name of the local file.</param>
            /// <param name="buffer">The buffer.</param>
            /// <param name="extension">The extension.</param>
            /// <returns></returns>
            protected static string[] DoBatchUpload(string groupName, IList<byte[]> filesBuffer, string[] filesExtension)
            {
                int filesCount = filesBuffer.Count;
                if (255 < filesCount)
                {
                    if (null != _logger)
                    {
                        _logger.ErrorFormat("批量上传文件的数量为:{0},超出了限定批上传文件数(限定批上传文件数为),请分多次上传.", filesCount);
                        throw new Exception("上传文件数超出批处理限制范围!");
                    }
                }
                if (null != _logger)
                {
                    _logger.InfoFormat("开始批量上传文件,批量上传文件的总数为:{0}.", filesCount);
                }
                TcpConnection storageConnection = GetStorageConnection(groupName);
                if (null != _logger)
                    _logger.InfoFormat("Storage服务器的IP是:{0}.端口为{1}", storageConnection.IpAddress, storageConnection.Port);
    
                if (filesBuffer.Count != filesExtension.Length)
                {
                    if (null != _logger)
                        _logger.ErrorFormat("上传文件数组与上传文件扩展名,上传文件数组长度为{0},文件扩展名数组长度为{1}。",
                            filesBuffer.Count, filesExtension.Length);
                    throw new Exception("上传文件数不匹配。");
                }
    
                //构建扩展名传输流
                byte[] filesExtensionBuffer = new byte[Protocol.FDFS_FILE_EXT_NAME_MAX_LEN * filesCount];
                byte[] fileExtensionBuffer = new byte[Protocol.FDFS_FILE_EXT_NAME_MAX_LEN];
                byte[] fileTempExtensionBuffer;
                for (int i = 0; i < filesExtension.Length; i++)
                {
                    if (string.IsNullOrEmpty(filesExtension[i]))
                    {
                        if (null != _logger)
                            _logger.Error("文件扩展名为空,终止文件上传。");
                        throw new Exception("未获得文件扩展名。");
                    }
                    fileTempExtensionBuffer = Encoding.GetEncoding(FastDFSService.Charset).GetBytes(filesExtension[i]);
                    int fileExtBufferLength = fileTempExtensionBuffer.Length;
                    if (fileExtBufferLength > Protocol.FDFS_FILE_EXT_NAME_MAX_LEN) fileExtBufferLength = Protocol.FDFS_FILE_EXT_NAME_MAX_LEN;
    
                    //协议归整
                    Array.Copy(fileTempExtensionBuffer, 0, fileExtensionBuffer, 0, fileExtBufferLength);
                    //加入网络传输
                    Array.Copy(fileExtensionBuffer, 0, filesExtensionBuffer, i * Protocol.FDFS_FILE_EXT_NAME_MAX_LEN, fileExtBufferLength);
                }
    
                //构建文件传输流
                long filesBufferLength = 0L;
                foreach (byte[] fileBuffer in filesBuffer)
                {
                    filesBufferLength += fileBuffer.LongLength;
                }
              
                //构建文件数量字节流
                byte[] filesCountBuffer = Util.LongToBuffer(filesCount);
    
                //构建头部协议块
                // Protocol.TRACKER_PROTO_PKG_LEN_SIZE * (filesCount + 2) 各个文件的长度+扩展名字节流的长度+文件字节流总共的长度
                byte[] headerBuffer = new byte[1 + Protocol.TRACKER_PROTO_PKG_LEN_SIZE * (filesCount + 2)];
                headerBuffer[0] = (byte)storageConnection.Index;//第一位为storage的index
                byte[] temp; 
                //每位表示每个文件的字节流长度
                for (int i = 0; i < filesBuffer.Count; i++)
                {
                    temp = Util.LongToBuffer(filesBuffer[i].LongLength);
                    Array.Copy(temp, 0, headerBuffer, 1 + i * Protocol.TRACKER_PROTO_PKG_LEN_SIZE, temp.LongLength);
                }
    
                temp = Util.LongToBuffer(filesExtensionBuffer.LongLength);//扩展名总共的长度
                Array.Copy(temp, 0, headerBuffer, 1 + filesBuffer.Count * Protocol.TRACKER_PROTO_PKG_LEN_SIZE, temp.LongLength);
                temp = Util.LongToBuffer(filesBufferLength);//文件字节流长度
                Array.Copy(temp, 0, headerBuffer, 1 + (filesBuffer.Count + 1) * Protocol.TRACKER_PROTO_PKG_LEN_SIZE, temp.LongLength);
    
                //构建协议传输流
                byte[] protocalBuffer = Util.PackHeader(Protocol.STORAGE_PROTO_CMD_Batch_UPLOAD,
                    //长度构成:一位storage的index+每个文件的字节长度+文件扩展名的总长度+文件字节的总长度
                                                   headerBuffer.Length +
                                                   filesCountBuffer.Length
                                                  + filesExtensionBuffer.Length + filesBufferLength,
                                                   0);
    
                _logger.InfoFormat("上传字节数为:{0}", headerBuffer.Length +
                                                   filesCountBuffer.Length
                                                  + filesExtensionBuffer.Length + filesBufferLength);
    
                Stream outStream = storageConnection.GetStream();
                outStream.Write(protocalBuffer, 0, protocalBuffer.Length);
                outStream.Write(filesCountBuffer, 0, filesCountBuffer.Length);
                outStream.Write(headerBuffer, 0, headerBuffer.Length);
                outStream.Write(filesExtensionBuffer, 0, filesExtensionBuffer.Length);
                foreach (byte[] buffer in filesBuffer)
                {
                    outStream.Write(buffer,0,buffer.Length);
                }
    
                Stream readStream;
                int fileNameBufferLength = Protocol.TRACKER_PROTO_PKG_LEN_SIZE + 128;//文件名长度+文件名内容
                byte[] tempBuffer;
                int tempReadSize = 0;
                int fileNameSize;
                byte[] tempFileNameBytes;
                char[] chars;
                int error;
                string[] filesName = new string[filesCount];
                for(int i = 0;i<filesCount;i++)
                {
                    readStream = storageConnection.GetStream();
                    tempBuffer = new byte[Protocol.TRACKER_PROTO_PKG_LEN_SIZE + 128];
                    tempReadSize = readStream.Read(tempBuffer, 0, fileNameBufferLength);
                    if(tempReadSize != fileNameBufferLength)
                    {
                        if(tempReadSize == 10)//文件未传输完成出现错误
                        {
                            error = tempBuffer[Protocol.PROTO_HEADER_STATUS_INDEX];
                            if (null != _logger)
                                _logger.ErrorFormat("上传文件中间发生异常,文件位置为:{0}.错误号为:{1}", i + 1, error);
                            throw new Exception("上传文件错误!");
                        }
                        if (null != _logger)
                            _logger.ErrorFormat("上传文件中间发生异常,文件位置为:{0}.未能返回错误号,错误header长度为:{1}", i + 1, tempReadSize);
                        throw new Exception("上传文件错误!");
                    }
    
                    fileNameSize = (int)Util.BufferToLong(tempBuffer, 0);
                    tempFileNameBytes = new byte[fileNameSize];
                    Array.Copy(tempBuffer, Protocol.TRACKER_PROTO_PKG_LEN_SIZE, tempFileNameBytes, 0, fileNameSize);
                    chars = Util.ToCharArray(tempFileNameBytes);
                    filesName[i] = new string(chars, 0, fileNameSize).Trim('\0').Trim();
    
                }
                readStream = storageConnection.GetStream();
                tempBuffer = new byte[10];
                tempReadSize = readStream.Read(tempBuffer, 0, 10);
                if (10 != tempReadSize)
                {
                    if (null != _logger)
                        _logger.ErrorFormat("文件上传完毕,并且文件路径已经全部返回客户端。但是发生服务器传输信息头错误。错误header长度为:{0}", tempReadSize);
                }
    
                error = tempBuffer[Protocol.PROTO_HEADER_STATUS_INDEX];
                if (0 != error)
                {
                    if (null != _logger)
                        _logger.ErrorFormat("文件上传完毕,并且文件路径已经全部返回客户端。但是服务器发生错误。错误号:{0}",error);
                }
    
                return filesName;
            }
     

           写这个程序的时候呢,因为是和服务器端程序一并调试用的,所以主要考虑了程序的完成功能程度,没有考虑性能,clr-gc等等这些东西。但是性能应该不会太差,clr的gc可能会忙一点。大家有兴趣的话,可以自己优化一下,其实这种东西不难的。

  • 相关阅读:
    java学生成绩管理系统
    7.19至7.25第八周学习情况
    8.12至8.18第七周学习情况
    8.5至8.11第六周学习情况
    7.29至8.4第五周学习情况
    《大道至简》读后感
    7.22至7.28第四周学习情况
    7.15至7.21第三周学习情况
    LeetCode 第三题:Longest Substring Without Repeating Characters
    哈希表(散列表)
  • 原文地址:https://www.cnblogs.com/Seapeak/p/1663421.html
Copyright © 2011-2022 走看看