첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ ByteSize.cs

using System;
using System.Globalization;

namespace TestProject
{
    /// <summary>
    /// 바이트 크기 구조체
    /// </summary>
    public struct ByteSize : IComparable<ByteSize>, IEquatable<ByteSize>
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 최소 값
        /// </summary>
        public static readonly ByteSize MinimumValue = ByteSize.FromBitCount(0);

        /// <summary>
        /// 최대 값
        /// </summary>
        public static readonly ByteSize MaximumValue = ByteSize.FromBitCount(long.MaxValue);

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 바이트당 비트 수
        /// </summary>
        public const long BIT_COUNT_PER_BYTE = 8;

        /// <summary>
        /// 킬로 바이트당 바이트 수
        /// </summary>
        public const long BYTE_COUNT_PER_KILO_BYTE = 1024;

        /// <summary>
        /// 메가 바이트당 바이트 수
        /// </summary>
        public const long BYTE_COUNT_PER_MEGA_BYTE = 1048576;

        /// <summary>
        /// 기가 바이트당 바이트 수
        /// </summary>
        public const long BYTE_COUNT_PER_GIGA_BYTE = 1073741824;

        /// <summary>
        /// 테라 바이트당 바이트 수
        /// </summary>
        public const long BYTE_COUNT_PER_TERA_BYTE = 1099511627776;

        /// <summary>
        /// 페타 바이트당 바이트 수
        /// </summary>
        public const long BYTE_COUNT_PER_PETA_BYTE = 1125899906842624;


        /// <summary>
        /// 비트 단위
        /// </summary>
        public const string BIT_UNIT = "b";

        /// <summary>
        /// 바이트 단위
        /// </summary>
        public const string BYTE_UNIT = "B";

        /// <summary>
        /// 킬로 바이트 단위
        /// </summary>
        public const string KILO_BYTE_UNIT = "KB";

        /// <summary>
        /// 메가 바이트 단위
        /// </summary>
        public const string MEGA_BYTE_UNIT = "MB";

        /// <summary>
        /// 기가 바이트 단위
        /// </summary>
        public const string GIGA_BYTE_UNIT = "GB";

        /// <summary>
        /// 테라 바이트 단위
        /// </summary>
        public const string TERA_BYTE_UINT = "TB";

        /// <summary>
        /// 페타 바이트 단위
        /// </summary>
        public const string PETA_BYTE_UNIT = "PB";

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 비트 수 - BitCount

        /// <summary>
        /// 비트 수
        /// </summary>
        public long BitCount { get; private set; }

        #endregion
        #region 바이트 수 - ByteCount

        /// <summary>
        /// 바이트 수
        /// </summary>
        public double ByteCount { get; private set; }

        #endregion
        #region 킬로 바이트 수 - KiloByteCount

        /// <summary>
        /// 킬로 바이트 수
        /// </summary>
        public double KiloByteCount { get; private set; }

        #endregion
        #region 메가 바이트 수 - MegaByteCount

        /// <summary>
        /// 메가 바이트 수
        /// </summary>
        public double MegaByteCount { get; private set; }

        #endregion
        #region 기가 바이트 수 - GigaByteCount

        /// <summary>
        /// 기가 바이트 수
        /// </summary>
        public double GigaByteCount { get; private set; }

        #endregion
        #region 테라 바이트 수 - TeraByteCount

        /// <summary>
        /// 테라 바이트 수
        /// </summary>
        public double TeraByteCount { get; private set; }

        #endregion
        #region 페타 바이트 수 - PetaByteCount

        /// <summary>
        /// 페타 바이트 수
        /// </summary>
        public double PetaByteCount { get; private set; }

        #endregion

        #region 가장 큰 단위 - LargestUnit

        /// <summary>
        /// 가장 큰 단위
        /// </summary>
        public string LargestUnit
        {
            get
            {
                if(Math.Abs(PetaByteCount) >= 1)
                {
                    return ByteSize.PETA_BYTE_UNIT;
                }
                else if(Math.Abs(TeraByteCount) >= 1)
                {
                    return ByteSize.TERA_BYTE_UINT;
                }
                else if(Math.Abs(GigaByteCount) >= 1)
                {
                    return ByteSize.GIGA_BYTE_UNIT;
                }
                else if(Math.Abs(MegaByteCount) >= 1)
                {
                    return ByteSize.MEGA_BYTE_UNIT;
                }
                else if(Math.Abs(KiloByteCount) >= 1)
                {
                    return ByteSize.KILO_BYTE_UNIT;
                }
                else if(Math.Abs(ByteCount) >= 1)
                {
                    return ByteSize.BYTE_UNIT;
                }

                return ByteSize.BIT_UNIT;
            }
        }

        #endregion
        #region 가장 큰 단위 값 - LargestUnitValue

        /// <summary>
        /// 가장 큰 단위 값
        /// </summary>
        public double LargestUnitValue
        {
            get
            {
                if(Math.Abs(PetaByteCount) >= 1)
                {
                    return PetaByteCount;
                }
                else if(Math.Abs(TeraByteCount) >= 1)
                {
                    return TeraByteCount;
                }
                else if(Math.Abs(GigaByteCount) >= 1)
                {
                    return GigaByteCount;
                }
                else if(Math.Abs(MegaByteCount) >= 1)
                {
                    return MegaByteCount;
                }
                else if(Math.Abs(KiloByteCount) >= 1)
                {
                    return KiloByteCount;
                }
                else if(Math.Abs(ByteCount) >= 1)
                {
                    return ByteCount;
                }

                return BitCount;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ByteSize(byteSize)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="byteSize">바이트 크기</param>
        public ByteSize(double byteSize)
        {
            BitCount = (long)Math.Ceiling(byteSize * BIT_COUNT_PER_BYTE);

            ByteCount = byteSize;

            KiloByteCount = byteSize / BYTE_COUNT_PER_KILO_BYTE;
            MegaByteCount = byteSize / BYTE_COUNT_PER_MEGA_BYTE;
            GigaByteCount = byteSize / BYTE_COUNT_PER_GIGA_BYTE;
            TeraByteCount = byteSize / BYTE_COUNT_PER_TERA_BYTE;
            PetaByteCount = byteSize / BYTE_COUNT_PER_PETA_BYTE;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 연산자 + 재정의하기 - operator +(source1, source2)

        /// <summary>
        /// 연산자 + 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static ByteSize operator +(ByteSize source1, ByteSize source2)
        {
            return new ByteSize(source1.ByteCount + source2.ByteCount);
        }

        #endregion
        #region 연산자 ++ 재정의하기 - operator ++(source)

        /// <summary>
        /// 연산자 ++ 재정의하기
        /// </summary>
        /// <param name="source">소스</param>
        /// <returns>바이트 크기</returns>
        public static ByteSize operator ++(ByteSize source)
        {
            return new ByteSize(source.ByteCount + 1);
        }

        #endregion
        #region 연산자 - 재정의하기 - operator -(source)

        /// <summary>
        /// 연산자 - 재정의하기
        /// </summary>
        /// <param name="source">소스</param>
        /// <returns>바이트 크기</returns>
        public static ByteSize operator -(ByteSize source)
        {
            return new ByteSize(-source.ByteCount);
        }

        #endregion
        #region 연산자 -- 재정의하기 - --(source)

        /// <summary>
        /// 연산자 -- 재정의하기
        /// </summary>
        /// <param name="source">소스</param>
        /// <returns>바이트 크기</returns>
        public static ByteSize operator --(ByteSize source)
        {
            return new ByteSize(source.ByteCount - 1);
        }

        #endregion
        #region 연산자 == 재정의하기 - operator ==(source1, source2)

        /// <summary>
        /// 연산자 == 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static bool operator ==(ByteSize source1, ByteSize source2)
        {
            return source1.BitCount == source2.BitCount;
        }

        #endregion
        #region 연산자 != 재정의하기 - operator !=(source1, source2)

        /// <summary>
        /// 연산자 != 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static bool operator !=(ByteSize source1, ByteSize source2)
        {
            return source1.BitCount != source2.BitCount;
        }

        #endregion
        #region 연산자 < 재정의하기 - operator <(source1, source2)

        /// <summary>
        /// 연산자 < 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static bool operator <(ByteSize source1, ByteSize source2)
        {
            return source1.BitCount < source2.BitCount;
        }

        #endregion
        #region 연산자 <= 재정의하기 - operator <=(source1, source2)

        /// <summary>
        /// 연산자 <= 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static bool operator <=(ByteSize source1, ByteSize source2)
        {
            return source1.BitCount <= source2.BitCount;
        }

        #endregion
        #region 연산자 > 재정의하기 - operator >(source1, source2)

        /// <summary>
        /// 연산자 > 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static bool operator >(ByteSize source1, ByteSize source2)
        {
            return source1.BitCount > source2.BitCount;
        }

        #endregion
        #region 연산자 >= 재정의하기 - operator >=(source1, source2)

        /// <summary>
        /// 연산자 >= 재정의하기
        /// </summary>
        /// <param name="source1">소스 1</param>
        /// <param name="source2">소스 2</param>
        /// <returns>바이트 크기</returns>
        public static bool operator >=(ByteSize source1, ByteSize source2)
        {
            return source1.BitCount >= source2.BitCount;
        }

        #endregion

        #region 비트 수에서 비트 크기 구하기 - FromBitCount(value)

        /// <summary>
        /// 비트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromBitCount(long value)
        {
            return new ByteSize(value / (double)BIT_COUNT_PER_BYTE);
        }

        #endregion
        #region 바이트 수에서 비트 크기 구하기 - FromByteCount(value)

        /// <summary>
        /// 바이트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromByteCount(double value)
        {
            return new ByteSize(value);
        }

        #endregion
        #region 킬로 바이트 수에서 비트 크기 구하기 - FromKiloByteCount(value)

        /// <summary>
        /// 킬로 바이트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromKiloByteCount(double value)
        {
            return new ByteSize(value * BYTE_COUNT_PER_KILO_BYTE);
        }

        #endregion
        #region 메가 바이트 수에서 비트 크기 구하기 - FromMegaByteCount(value)

        /// <summary>
        /// 메가 바이트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromMegaByteCount(double value)
        {
            return new ByteSize(value * BYTE_COUNT_PER_MEGA_BYTE);
        }

        #endregion
        #region 기가 바이트 수에서 비트 크기 구하기 - FromGigaByteCount(value)

        /// <summary>
        /// 기가 바이트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromGigaByteCount(double value)
        {
            return new ByteSize(value * BYTE_COUNT_PER_GIGA_BYTE);
        }

        #endregion
        #region 테라 바이트 수에서 비트 크기 구하기 - FromTeraByteCount(value)

        /// <summary>
        /// 테라 바이트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromTeraByteCount(double value)
        {
            return new ByteSize(value * BYTE_COUNT_PER_TERA_BYTE);
        }

        #endregion
        #region 페타 바이트 수에서 비트 크기 구하기 - FromPetaByteCount(value)

        /// <summary>
        /// 페타 바이트 수에서 비트 크기 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비트 크기</returns>
        public static ByteSize FromPetaByteCount(double value)
        {
            return new ByteSize(value * BYTE_COUNT_PER_PETA_BYTE);
        }

        #endregion

        #region 파싱 시도하기 - TryParse(source, value)

        /// <summary>
        /// 파싱 시도하기
        /// </summary>
        /// <param name="source">소스</param>
        /// <param name="value">값</param>
        /// <returns>처리 결과</returns>
        public static bool TryParse(string source, out ByteSize value)
        {
            if(string.IsNullOrWhiteSpace(source))
            {
                throw new ArgumentNullException("source", "String is null or whitespace");
            }

            value = new ByteSize();

            source = source.TrimStart();

            int  i                = 0;
            bool found            = false;
            char decimalSeparator = Convert.ToChar(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
            char groupSeparator   = Convert.ToChar(NumberFormatInfo.CurrentInfo.NumberGroupSeparator);

            int sourceLength = source.Length;

            for(i = 0; i < sourceLength; i++)
            {
                if(!(char.IsDigit(source[i]) || source[i] == decimalSeparator || source[i] == groupSeparator))
                {
                    found = true;

                    break;
                }
            }

            if(found == false)
            {
                return false;
            }

            int lastNumber = i;

            string numberPart = source.Substring(0, lastNumber).Trim();
            string sizePart   = source.Substring(lastNumber, source.Length - lastNumber).Trim();

            double number;

            if(!double.TryParse(numberPart, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out number))
            {
                return false;
            }

            switch(sizePart)
            {
                case "b" :

                    if(number % 1 != 0)
                    {
                        return false;
                    }

                    value = FromBitCount((long)number);

                    break;

                case "B" :

                    value = FromByteCount(number);

                    break;

                case "KB" :
                case "kB" :
                case "kb" :

                    value = FromKiloByteCount(number);

                    break;

                case "MB" :
                case "mB" :
                case "mb" :

                    value = FromMegaByteCount(number);

                    break;

                case "GB" :
                case "gB" :
                case "gb" :

                    value = FromGigaByteCount(number);

                    break;

                case "TB" :
                case "tB" :
                case "tb" :

                    value = FromTeraByteCount(number);

                    break;

                case "PB" :
                case "pB" :
                case "pb" :

                    value = FromPetaByteCount(number);

                    break;
            }

            return true;
        }

        #endregion
        #region 파싱하기 - Parse(source)

        /// <summary>
        /// 파싱하기
        /// </summary>
        /// <param name="source">소스</param>
        /// <returns>바이트 크기</returns>
        public static ByteSize Parse(string source)
        {
            ByteSize byteSize;

            if(TryParse(source, out byteSize))
            {
                return byteSize;
            }

            throw new FormatException("source is not in the correct format");
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 문자열 구하기 - ToString(format, formatProvider)

        /// <summary>
        /// 문자열 구하기
        /// </summary>
        /// <param name="format">포맷 문자열</param>
        /// <param name="formatProvider">포맷 공급자</param>
        /// <returns>문자열</returns>
        public string ToString(string format, IFormatProvider formatProvider)
        {
            if(!format.Contains("#") && !format.Contains("0"))
            {
                format = "#.## " + format;
            }

            if(formatProvider == null)
            {
                formatProvider = CultureInfo.CurrentCulture;
            }

            Func<string, bool> containsFunc = s => format.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) != -1;

            Func<double, string> outputFimc = n => n.ToString(format, formatProvider);

            if(containsFunc("PB"))
            {
                return outputFimc(PetaByteCount);
            }
            else if(containsFunc("TB"))
            {
                return outputFimc(TeraByteCount);
            }
            else if(containsFunc("GB"))
            {
                return outputFimc(GigaByteCount);
            }
            else if(containsFunc("MB"))
            {
                return outputFimc(MegaByteCount);
            }
            else if(containsFunc("KB"))
            {
                return outputFimc(KiloByteCount);
            }

            if(format.IndexOf(ByteSize.BYTE_UNIT) != -1)
            {
                return outputFimc(this.ByteCount);
            }

            if(format.IndexOf(ByteSize.BIT_UNIT) != -1)
            {
                return outputFimc(this.BitCount);
            }

            return string.Format("{0} {1}", LargestUnitValue.ToString(format, formatProvider), LargestUnit);
        }

        #endregion
        #region 문자열 구하기 - ToString(formatString)

        /// <summary>
        /// 문자열 구하기
        /// </summary>
        /// <param name="formatString">포맷 문자열</param>
        /// <returns>문자열</returns>
        public string ToString(string formatString)
        {
            return ToString(formatString, CultureInfo.CurrentCulture);
        }

        #endregion
        #region 문자열 구하기 - ToString()

        /// <summary>
        /// 문자열 구하기
        /// </summary>
        /// <returns>문자열</returns>
        public override string ToString()
        {
            return ToString("#.##", CultureInfo.CurrentCulture);
        }

        #endregion

        #region 동일 여부 구하기 - Equals(value)

        /// <summary>
        /// 동일 여부 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>동일 여부</returns>
        public override bool Equals(object value)
        {
            if(value == null)
            {
                return false;
            }

            ByteSize other;

            if(value is ByteSize)
            {
                other = (ByteSize)value;
            }
            else
            {
                return false;
            }

            return Equals(other);
        }

        #endregion
        #region 동일 여부 구하기 - Equals(value)

        /// <summary>
        /// 동일 여부 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>덩일 여부</returns>
        public bool Equals(ByteSize value)
        {
            return this.BitCount == value.BitCount;
        }

        #endregion

        #region 해시 코드 구하기 - GetHashCode()

        /// <summary>
        /// 해시 코드 구하기
        /// </summary>
        /// <returns>해시 코드</returns>
        public override int GetHashCode()
        {
            return BitCount.GetHashCode();
        }

        #endregion

        #region 비교하기 - CompareTo(value)

        /// <summary>
        /// 비교하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>비교 결과</returns>
        public int CompareTo(ByteSize value)
        {
            return this.BitCount.CompareTo(value.BitCount);
        }

        #endregion

        #region 추가하기 - Add(value)

        /// <summary>
        /// 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>추가 값</returns>
        public ByteSize Add(ByteSize value)
        {
            return new ByteSize(ByteCount + value.ByteCount);
        }

        #endregion
        #region 비트 수 추가하기 - AddBitCount(value)

        /// <summary>
        /// 비트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddBitCount(long value)
        {
            return this + FromBitCount(value);
        }

        #endregion
        #region 바이트 수 추가하기 - AddByteCount(value)

        /// <summary>
        /// 바이트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddByteCount(double value)
        {
            return this + ByteSize.FromByteCount(value);
        }

        #endregion
        #region 킬로 바이트 수 추가하기 - AddKiloByteCount(value)

        /// <summary>
        /// 킬로 바이트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddKiloByteCount(double value)
        {
            return this + ByteSize.FromKiloByteCount(value);
        }

        #endregion
        #region 메가 바이트 수 추가하기 - AddMegaByteCount(value)

        /// <summary>
        /// 메가 바이트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddMegaByteCount(double value)
        {
            return this + ByteSize.FromMegaByteCount(value);
        }

        #endregion
        #region 기가 바이트 수 추가하기 - AddGigaByteCount(value)

        /// <summary>
        /// 기가 바이트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddGigaByteCount(double value)
        {
            return this + ByteSize.FromGigaByteCount(value);
        }

        #endregion
        #region 테라 바이트 수 추가하기 - AddTeraByteCount(value)

        /// <summary>
        /// 테라 바이트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddTeraByteCount(double value)
        {
            return this + ByteSize.FromTeraByteCount(value);
        }

        #endregion
        #region 페타 바이트 수 추가하기 - AddPetaByteCount(value)

        /// <summary>
        /// 페타 바이트 수 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize AddPetaByteCount(double value)
        {
            return this + ByteSize.FromPetaByteCount(value);
        }

        #endregion

        #region 빼기 - Subtract(value)

        /// <summary>
        /// 빼기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>바이트 크기</returns>
        public ByteSize Subtract(ByteSize value)
        {
            return new ByteSize(ByteCount - value.ByteCount);
        }

        #endregion
    }
}

 

728x90

 

▶ Program.cs

using System;

namespace TestProject
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            ByteSize size = new ByteSize(1029343342);

            Console.WriteLine(size.ByteCount    );
            Console.WriteLine(size.KiloByteCount);
            Console.WriteLine(size.MegaByteCount);
            Console.WriteLine(size.GigaByteCount);
            Console.WriteLine(size.TeraByteCount);

            Console.WriteLine($"{size.LargestUnitValue.ToString("F")}{size.LargestUnit}");
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요