/// <summary>
        /// 上传文件.
        /// </summary>
        /// <param name="groupName">Name of the group.</param>
        /// <param name="localFileName">Name of the local file.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="extension">The extension.</param>
        /// <param name="metadatas">The metadatas.</param>
        /// <returns></returns>
        protected static string[] DoUpload(string groupName, string localFileName, byte[] buffer,
                                           string extension, NameValuePair[] metadatas)
        {
            TcpConnection storageConnection = GetStorageConnection(groupName);

            if (null != _logger)
            {
                _logger.InfoFormat("Storage服务器的IP是:{0}.端口为{1}", storageConnection.IpAddress, storageConnection.Port);
            }
            long totalBytes = 0;

            try
            {
                long       length;
                FileStream stream;

                byte[] metadatasBuffer = metadatas == null
                                              ? new byte[0]
                                              : Encoding.GetEncoding(FastDFSService.Charset).GetBytes(Util.PackMetadata(metadatas));

                byte[] bufferSize = new byte[1 + 2 * Protocol.TRACKER_PROTO_PKG_LEN_SIZE];

                if (!string.IsNullOrEmpty(localFileName))
                {
                    FileInfo fileInfo = new FileInfo(localFileName);
                    length = fileInfo.Exists ? fileInfo.Length : 0;
                    stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
                }
                else
                {
                    length = buffer.Length;
                    stream = null;
                }

                byte[] extensionBuffer = new byte[Protocol.FDFS_FILE_EXT_NAME_MAX_LEN];
                Util.InitializeBuffer(extensionBuffer, 0);
                if (!string.IsNullOrEmpty(extension))
                {
                    byte[] bs           = Encoding.GetEncoding(FastDFSService.Charset).GetBytes(extension);
                    int    ext_name_len = bs.Length;
                    if (ext_name_len > Protocol.FDFS_FILE_EXT_NAME_MAX_LEN)
                    {
                        ext_name_len = Protocol.FDFS_FILE_EXT_NAME_MAX_LEN;
                    }
                    Array.Copy(bs, 0, extensionBuffer, 0, ext_name_len);
                }

                Util.InitializeBuffer(bufferSize, 0);
                bufferSize[0] = (byte)storageConnection.Index;
                byte[] hexBuffer = Util.LongToBuffer(metadatasBuffer.Length);
                Array.Copy(hexBuffer, 0, bufferSize, 1, hexBuffer.Length);
                hexBuffer = Util.LongToBuffer(length);
                Array.Copy(hexBuffer, 0, bufferSize, 1 + Protocol.TRACKER_PROTO_PKG_LEN_SIZE, hexBuffer.Length);

                byte[] header = Util.PackHeader(Protocol.STORAGE_PROTO_CMD_UPLOAD_FILE,
                                                1 + 2 * Protocol.TRACKER_PROTO_PKG_LEN_SIZE +
                                                Protocol.FDFS_FILE_EXT_NAME_MAX_LEN + metadatasBuffer.Length + length,
                                                0);
                Stream outStream = storageConnection.GetStream();
                outStream.Write(header, 0, header.Length);
                outStream.Write(bufferSize, 0, bufferSize.Length);
                outStream.Write(extensionBuffer, 0, extensionBuffer.Length);
                outStream.Write(metadatasBuffer, 0, metadatasBuffer.Length);
                if (stream != null)
                {
                    int    readBytes;
                    byte[] buff = new byte[128 * 1024];

                    while ((readBytes = Util.ReadInput(stream, buff, 0, buff.Length)) >= 0)
                    {
                        if (readBytes == 0)
                        {
                            continue;
                        }
                        outStream.Write(buff, 0, readBytes);
                        totalBytes += readBytes;
                    }
                }
                else
                {
                    outStream.Write(buffer, 0, buffer.Length);
                }

                PackageInfo pkgInfo = Util.RecvPackage(storageConnection.GetStream(), Protocol.STORAGE_PROTO_CMD_RESP, -1);
                if (pkgInfo.ErrorNo != 0)
                {
                    return(null);
                }

                if (pkgInfo.Body.Length <= Protocol.FDFS_GROUP_NAME_MAX_LEN)
                {
                    throw new Exception(string.Format("_body length: {0} <= {1}",
                                                      pkgInfo.Body.Length, Protocol.FDFS_GROUP_NAME_MAX_LEN));
                }

                char[]   chars          = Util.ToCharArray(pkgInfo.Body);
                string   newGroupName   = new string(chars, 0, Protocol.FDFS_GROUP_NAME_MAX_LEN).Trim();
                string   remoteFileName = new string(chars, Protocol.FDFS_GROUP_NAME_MAX_LEN, pkgInfo.Body.Length - Protocol.FDFS_GROUP_NAME_MAX_LEN);
                string[] results        = new string[]
                {
                    newGroupName, remoteFileName
                };
                return(results);
            }
            finally
            {
                storageConnection.Close(false, true);
            }
        }
        /// <summary>
        /// 得到存储服务器
        /// </summary>
        /// <param name="groupName">存储的文件组名.</param>
        /// <returns></returns>
        public static StorageServerInfo GetStoreStorage(string groupName)
        {
            TcpConnection trackerConnection = GetTrackerConnection(groupName);

            if (null != _logger)
            {
                _logger.InfoFormat("连接Tracker服务器的IP是:{0},端口是{1}", trackerConnection.IpAddress, trackerConnection.Port);
            }
            Stream stream = trackerConnection.GetStream();

            if (null == trackerConnection)
            {
                trackerConnection = GetTrackerConnection(groupName);
                if (trackerConnection == null)
                {
                    return(null);
                }
            }

            try
            {
                byte cmd;
                int  length;
                if (string.IsNullOrEmpty(groupName))
                {
                    cmd    = Protocol.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP;
                    length = 0;
                }
                else
                {
                    cmd    = Protocol.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP;
                    length = Protocol.FDFS_GROUP_NAME_MAX_LEN;
                }

                byte[] headerBuffer = Util.PackHeader(cmd, length, 0);
                stream.Write(headerBuffer, 0, headerBuffer.Length);

                if (!string.IsNullOrEmpty(groupName))
                {
                    byte[] buffer          = Encoding.GetEncoding(FastDFSService.Charset).GetBytes(groupName);
                    byte[] groupNameBuffer = new byte[Protocol.FDFS_GROUP_NAME_MAX_LEN];

                    int group_len = buffer.Length <= Protocol.FDFS_GROUP_NAME_MAX_LEN
                                        ? buffer.Length
                                        : Protocol.FDFS_GROUP_NAME_MAX_LEN;
                    Util.InitializeBuffer(groupNameBuffer, 0);
                    Array.Copy(buffer, 0, groupNameBuffer, 0, group_len);
                    stream.Write(groupNameBuffer, 0, groupNameBuffer.Length);
                }

                PackageInfo pkgInfo = Util.RecvPackage(trackerConnection.GetStream(),
                                                       Protocol.TRACKER_PROTO_CMD_SERVICE_RESP,
                                                       Protocol.TRACKER_QUERY_STORAGE_STORE_BODY_LEN);
                if (pkgInfo.ErrorNo != 0)
                {
                    return(null);
                }

                string ipAddress =
                    new String(Util.ToCharArray(pkgInfo.Body), Protocol.FDFS_GROUP_NAME_MAX_LEN, Protocol.FDFS_IPADDR_SIZE - 1).Trim();

                if (ipAddress.EndsWith("\0\0"))
                {
                    ipAddress = ipAddress.Remove(ipAddress.Length - 2);
                }
                if (ipAddress.EndsWith("\0"))
                {
                    ipAddress = ipAddress.Remove(ipAddress.Length - 1);
                }

                int port =
                    (int)Util.BufferToLong(pkgInfo.Body, Protocol.FDFS_GROUP_NAME_MAX_LEN + Protocol.FDFS_IPADDR_SIZE - 1);
                byte body = pkgInfo.Body[Protocol.TRACKER_QUERY_STORAGE_STORE_BODY_LEN - 1];

                return(new StorageServerInfo(ipAddress.Trim(), port, body));
            }
            finally
            {
                trackerConnection.Close(true, false);
            }
        }
Exemple #3
0
        /// <summary>
        /// 上传文件.
        /// </summary>
        /// <param name="groupName">Name of the group.</param>
        /// <param name="localFileName">Name of the local file.</param>
        /// <param name="buffer">The buffer.</param>
        /// <param name="extension">The extension.</param>
        /// <param name="metadatas">The metadatas.</param>
        /// <returns></returns>
        protected static string[] DoUpload(string groupName, string localFileName, byte[] buffer,
                                           string extension, NameValuePair[] metadatas)
        {
            bool     isGoing = false;
            DateTime begin   = DateTime.Now;

            do
            {
                TimeSpan span = DateTime.Now.Subtract(begin);
                if ((int)span.TotalSeconds > FastDFSService.NetworkTimeout / 1000) //超过网络延迟还未成功上传图片,即失败
                {
                    break;
                }
                TcpConnection storageConnection = GetStorageConnection(groupName);
                if (null != _logger)
                {
                    _logger.InfoFormat("Storage服务器的IP是:{0}.端口为{1}", storageConnection.IpAddress, storageConnection.Port);
                }
                long totalBytes = 0;
                try
                {
                    long       length;
                    FileStream stream;

                    byte[] metadatasBuffer = metadatas == null
                                                 ? new byte[0]
                                                 : Encoding.GetEncoding(FastDFSService.Charset).GetBytes(
                        Util.PackMetadata(metadatas));
                    byte[] contentBuffer = buffer;
                    //byte[] bufferSize = new byte[1 + 2 * Protocol.TRACKER_PROTO_PKG_LEN_SIZE];
                    byte storePathIndex = (byte)storageConnection.Index;
                    if (!string.IsNullOrEmpty(localFileName))
                    {
                        FileInfo fileInfo = new FileInfo(localFileName);
                        length = fileInfo.Exists ? fileInfo.Length : 0;
                        stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
                    }
                    else
                    {
                        length = buffer.Length;
                        stream = null;
                    }
                    #region 拷贝后缀扩展名值
                    byte[] extensionBuffer = new byte[Protocol.FDFS_FILE_EXT_NAME_MAX_LEN];
                    Util.InitializeBuffer(extensionBuffer, 0);
                    if (!string.IsNullOrEmpty(extension))
                    {
                        byte[] bs           = Util.StringToByte(extension);
                        int    ext_name_len = bs.Length;
                        if (ext_name_len > Protocol.FDFS_FILE_EXT_NAME_MAX_LEN)
                        {
                            ext_name_len = Protocol.FDFS_FILE_EXT_NAME_MAX_LEN;
                        }
                        Array.Copy(bs, 0, extensionBuffer, 0, ext_name_len);
                    }
                    #endregion
                    length = 1 + Protocol.FDFS_PROTO_PKG_LEN_SIZE + Protocol.FDFS_FILE_EXT_NAME_MAX_LEN + buffer.Length;
                    byte[] bodyBuffer = new byte[length];
                    bodyBuffer[0] = storePathIndex;
                    byte[] fileSizeBuffer = Util.LongToBuffer(buffer.Length);
                    Array.Copy(fileSizeBuffer, 0, bodyBuffer, 1, fileSizeBuffer.Length);
                    Array.Copy(extensionBuffer, 0, bodyBuffer, 1 + Protocol.FDFS_PROTO_PKG_LEN_SIZE, extensionBuffer.Length);
                    Array.Copy(contentBuffer, 0, bodyBuffer, 1 + Protocol.FDFS_PROTO_PKG_LEN_SIZE + Protocol.FDFS_FILE_EXT_NAME_MAX_LEN, contentBuffer.Length);
                    //Util.InitializeBuffer(bufferSize, 0);
                    //bufferSize[0] = (byte)storageConnection.Index;
                    //byte[] hexBuffer = Util.LongToBuffer(metadatasBuffer.Length);
                    //Array.Copy(hexBuffer, 0, bufferSize, 1, hexBuffer.Length);
                    //hexBuffer = Util.LongToBuffer(length);
                    //Array.Copy(hexBuffer, 0, bufferSize, 1 + Protocol.TRACKER_PROTO_PKG_LEN_SIZE, hexBuffer.Length);

                    byte[] header = Util.PackHeader(Protocol.STORAGE_PROTO_CMD_UPLOAD_FILE, length, 0);

                    PackageInfo pkgInfo = null;
                    if (!storageConnection.Connected)
                    {
                        storageConnection.Connect();
                    }

                    NetworkStream outStream = storageConnection.GetStream();

                    outStream.Write(header, 0, header.Length);
                    outStream.Write(bodyBuffer, 0, bodyBuffer.Length);
                    //outStream.Write(extensionBuffer, 0, extensionBuffer.Length);
                    //outStream.Write(metadatasBuffer, 0, metadatasBuffer.Length);
                    if (stream != null)
                    {
                        int    readBytes;
                        byte[] buff = new byte[128 * 1024];

                        while ((readBytes = Util.ReadInput(stream, buff, 0, buff.Length)) >= 0)
                        {
                            if (readBytes == 0)
                            {
                                continue;
                            }
                            outStream.Write(buff, 0, readBytes);
                            totalBytes += readBytes;
                        }
                    }
                    else
                    {
                        outStream.Write(buffer, 0, buffer.Length);
                    }

                    pkgInfo = Util.RecvPackage(outStream, Protocol.STORAGE_PROTO_CMD_RESP, -1, "storage");

                    if (pkgInfo.ErrorNo != 0)
                    {
                        return(null);
                    }

                    if (pkgInfo.Body.Length <= Protocol.FDFS_GROUP_NAME_MAX_LEN)
                    {
                        throw new Exception(string.Format("_body length: {0} <= {1}",
                                                          pkgInfo.Body.Length, Protocol.FDFS_GROUP_NAME_MAX_LEN));
                    }

                    char[] chars          = Util.ToCharArray(pkgInfo.Body);
                    string newGroupName   = new string(chars, 0, Protocol.FDFS_GROUP_NAME_MAX_LEN).Trim();
                    string remoteFileName = new string(chars, Protocol.FDFS_GROUP_NAME_MAX_LEN,
                                                       pkgInfo.Body.Length - Protocol.FDFS_GROUP_NAME_MAX_LEN);
                    string[] results = new string[]
                    {
                        newGroupName, remoteFileName, storageConnection.IpAddress
                    };
                    return(results);
                }
                catch (Exception exc)
                {
                    try
                    {
                        storageConnection.GetStream().Close();
                    }
                    catch
                    {
                    }
                    if (null != _logger)
                    {
                        _logger.Error(string.Format("上传文件发生异常!异常类型:{0},详细信息:{1}!", exc.InnerException.GetType(), exc));
                    }
                    storageConnection.Close();
                    isGoing = true;
                }
                finally
                {
                    storageConnection.Close(false, true);
                }
            } while (isGoing);
            return(null);
        }