public virtual bool DeleteFile(FtpContext context, string filename)
        {
            string filepath = GetStoragePath(context, filename);

            if (File.Exists(filepath))
            {
                FileInfo file = new FileInfo(filepath);

                long fileLength = file.Length;

                try
                {
                    File.Delete(filepath);
                    context.ChangeSpace(0 - fileLength);
                    return(true);
                }
                catch (UnauthorizedAccessException uae)
                {
                    AppServer.Logger.Error(uae);
                    context.SetError(FtpCoreResource.PermissionDenied_550);
                    return(false);
                }
                catch (Exception e)
                {
                    AppServer.Logger.Error(e);
                    context.SetError(FtpCoreResource.DeleteFailed_450, filename);
                    return(false);
                }
            }
            else
            {
                context.SetError(FtpCoreResource.NotFound_550);
                return(false);
            }
        }
        protected bool StoreFile(FtpContext context, string filename, Stream stream, StoreOption option)
        {
            int bufLen = 1024 * 10;

            byte[] buffer    = new byte[bufLen];
            int    read      = 0;
            long   totalRead = 0;

            int speed = context.User.MaxUploadSpeed;

            FileStream fs = null;

            try
            {
                string filePath = GetStoragePath(context, filename);

                if (context.Offset > 0 && option.AppendOriginalFile) //Append
                {
                    FileInfo file = new FileInfo(filePath);

                    if (context.Offset != file.Length)
                    {
                        context.Status  = FtpStatus.Error;
                        context.Message = "Invalid offset";
                        return(false);
                    }

                    fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Write, bufLen);
                }
                else
                {
                    if (File.Exists(filePath))
                    {
                        FileInfo file       = new FileInfo(filePath);
                        var      fileLength = file.Length;
                        File.Delete(filePath);
                        context.ChangeSpace(0 - fileLength);
                    }

                    fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write, FileShare.Write, bufLen);
                }


                DateTime dtStart;
                TimeSpan ts;
                int      usedMs = 0, predictMs = 0;

                dtStart = DateTime.Now;

                while ((read = stream.Read(buffer, 0, bufLen)) > 0)
                {
                    fs.Write(buffer, 0, read);
                    totalRead += read;
                    context.ChangeSpace(read);

                    if (speed > 0) // if speed <=0, then no speed limitation
                    {
                        ts        = DateTime.Now.Subtract(dtStart);
                        usedMs    = (int)ts.TotalMilliseconds;
                        predictMs = read / speed;

                        if (predictMs > usedMs) //Speed control
                        {
                            Thread.Sleep(predictMs - usedMs);
                        }

                        dtStart = DateTime.Now;
                    }
                }

                return(true);
            }
            catch (Exception e)
            {
                AppServer.Logger.Error(e);
                context.Status  = FtpStatus.Error;
                context.Message = "Store file error";
                return(false);
            }
            finally
            {
                option.TotalRead = totalRead;

                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                    fs = null;
                }
            }
        }
        protected bool StoreFile(FtpContext context, string filename, Stream stream, StoreOption option)
        {
            int bufLen = 1024 * 10;
            byte[] buffer = new byte[bufLen];
            int read = 0;
            long totalRead = 0;

            int speed = context.User.MaxUploadSpeed;

            FileStream fs = null;

            try
            {
                string filePath = GetStoragePath(context, filename);

                if (context.Offset > 0 && option.AppendOriginalFile) //Append
                {
                    FileInfo file = new FileInfo(filePath);

                    if (context.Offset != file.Length)
                    {
                        context.Status = FtpStatus.Error;
                        context.Message = "Invalid offset";
                        return false;
                    }

                    fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Write, bufLen);
                }
                else
                {
                    if (File.Exists(filePath))
                    {
                        FileInfo file = new FileInfo(filePath);
                        var fileLength = file.Length;
                        File.Delete(filePath);
                        context.ChangeSpace(0 - fileLength);
                    }

                    fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write, FileShare.Write, bufLen);
                }


                DateTime dtStart;
                TimeSpan ts;
                int usedMs = 0, predictMs = 0;

                dtStart = DateTime.Now;

                while ((read = stream.Read(buffer, 0, bufLen)) > 0)
                {
                    fs.Write(buffer, 0, read);
                    totalRead += read;
                    context.ChangeSpace(read);

                    if (speed > 0) // if speed <=0, then no speed limitation
                    {
                        ts = DateTime.Now.Subtract(dtStart);
                        usedMs = (int)ts.TotalMilliseconds;
                        predictMs = read / speed;

                        if (predictMs > usedMs) //Speed control
                        {
                            Thread.Sleep(predictMs - usedMs);
                        }

                        dtStart = DateTime.Now;
                    }
                }

                return true;
            }
            catch (Exception e)
            {
                AppServer.Logger.Error(e);
                context.Status = FtpStatus.Error;
                context.Message = "Store file error";
                return false;
            }
            finally
            {
                option.TotalRead = totalRead;

                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                    fs = null;
                }
            }
        }
        public virtual bool DeleteFile(FtpContext context, string filename)
        {
            string filepath = GetStoragePath(context, filename);

            if (File.Exists(filepath))
            {
                FileInfo file = new FileInfo(filepath);

                long fileLength = file.Length;

                try
                {
                    File.Delete(filepath);
                    context.ChangeSpace(0 - fileLength);
                    return true;
                }
                catch (UnauthorizedAccessException uae)
                {
                    AppServer.Logger.Error(uae);
                    context.SetError(FtpCoreResource.PermissionDenied_550);
                    return false;
                }
                catch (Exception e)
                {
                    AppServer.Logger.Error(e);
                    context.SetError(FtpCoreResource.DeleteFailed_450, filename);
                    return false;
                }
            }
            else
            {
                context.SetError(FtpCoreResource.NotFound_550);
                return false;
            }
        }