在進行程式設計的時候,有時會需要進行檔案大小或是資料大小的輸入與輸出,甚至會需要對其做一些運算。做這件事有什麼困難的嗎?我們應該都知道,8個位元是1個位元組(Byte),1000個位元組是1KB,而1000KB是1MB。在設計程式的時候,如果要將一個以位元組為單位的值,選擇適當的單位來輸出(例如1200位元組要輸出成1.20MB、5555555位元組要輸出成5.56MB)的話,就必須要多撰寫幾行程式來完成。如果是資料輸入的時候,假設使用者輸入的是「3.6MB」,程式也許需要多撰寫幾行程式,將其轉為「3600000」來儲存,表示為「3600000個位元組」;輸入「25KB」,就要轉成「25000」。這些雖然都是簡單的事情,且所需要的程式碼量也不大,但就是由於簡單又常用,每次都要在不同專案寫一樣的程式去處理就會覺得很煩躁,所以乾脆將其發展為一個獨立的套件,就能不斷地重複使用了。
Byte Unit
「Byte Unit」是筆者開發的套件,實現了位元組(B)、KB、KiB、MB、MiB、GB、GiB、TB、TiB、PB、PiB、EB、EiB、ZB、ZiB、YB、YiB的大小單位換算。
KB、MB、GB、TB、PB、EB、ZB、YB等都是基於1000的單位,而KiB、MiB、GiB、TiB、PiB、EiB、ZiB、YiB等則是基於1024的單位。
1KB = 1000 1KiB = 1024 1MB = 1000000 1MiB = 1048576 1GB = 1000000000 1GiB = 1073741824 1TP = 1000000000000 1TiB = 1099511627776 1PB = 1000000000000000 1PiB = 1125899906842624 1EB = 1000000000000000000 1EiB = 1152921504606846976 1ZB = 1000000000000000000000 1ZiB = 1180591620717411303424 1YB = 1000000000000000000000000 1YiB = 1208925819614629174706176
預設儲存位元組的數值型別是採用u64
,不過也可以啟用u128
特色來改為使用u128
數值型別,最大支援的單位才會從EiB變成YiB。
Crates.io
Cargo.toml
使用方法
Unit
Unit
列舉可以表示位元或是位元組的單位。
use byte_unit::Unit;
assert_eq!("KB", Unit::KB.as_str());
assert_eq!("MiB", Unit::MiB.as_str());
assert_eq!(Unit::KB, Unit::parse_str("K", true, true).unwrap());
assert_eq!(Unit::Kbit, Unit::parse_str("K", true, false).unwrap());
assert_eq!(Unit::KB, Unit::parse_str("KB", true, true).unwrap());
assert_eq!(Unit::KB, Unit::parse_str("Kb", true, true).unwrap());
assert_eq!(Unit::Kbit, Unit::parse_str("Kbit", true, true).unwrap());
assert_eq!(Unit::KB, Unit::parse_str("KB", false, true).unwrap());
assert_eq!(Unit::Kbit, Unit::parse_str("Kb", false, true).unwrap());
Byte
Byte
結構體可以表示位元組的大小。
from_*
關聯函數可以被用來從不同的資料型別建立Byte
實體。as_*
方法能以基本資料型別來取得大小。
use byte_unit::{Byte, Unit};
assert_eq!(15000, Byte::from_u64(15000).as_u64());
assert_eq!(15000, Byte::from_u64_with_unit(15, Unit::KB).unwrap().as_u64());
我們也可以解析一個字串剌產生初一個Byte
實體。
use byte_unit::Byte;
assert_eq!(50840000, Byte::parse_str("50.84 MB", true).unwrap().as_u64());
一個Byte
實體可以被精確地格式化成字串。更多用法請參考API文件。
use byte_unit::Byte;
let byte = Byte::from_u64(15500);
assert_eq!("15500", byte.to_string());
assert_eq!("15.5 KB", format!("{byte:#}"));
assert_eq!("15500 B", format!("{byte:#.0}"));
計算
有add
、subtract
、multiply
和divide
方法可以使用。
use byte_unit::Byte;
let a = Byte::from_u64(15500);
let b = Byte::from_u64(500);
assert_eq!(16000, a.add(b).unwrap().as_u64());
assert_eq!(15000, a.subtract(b).unwrap().as_u64());
assert_eq!(31000, a.multiply(2).unwrap().as_u64());
assert_eq!(3100, a.divide(5).unwrap().as_u64());
找出適當的單位
如果我們想要替某個Byte
實體找出適當的單位,get_exact_unit
和get_recoverable_unit
方法很有用。
use byte_unit::{Byte, Unit};
let byte = Byte::from_u64(50840000);
assert_eq!((50840, Unit::KB), byte.get_exact_unit(false));
assert_eq!((50.84f64.try_into().unwrap(), Unit::MB), byte.get_recoverable_unit(false, 2));
assert_eq!((50840.into(), Unit::KB), byte.get_recoverable_unit(false, 0));
AdjustedByte
AdjustedByte
結構體可以被用來粗略地表示位元組的大小和單位。
我們可以使用get_adjusted_unit
方法來改變某個Byte
實體的單位。
一個AdjustedByte
實體可以被格式化成字串。更多用法請參考API文件。
use byte_unit::{Byte, Unit};
let byte = Byte::parse_str("123KiB", true).unwrap();
let adjusted_byte = byte.get_adjusted_unit(Unit::KB);
assert_eq!("125.952 KB", adjusted_byte.to_string());
assert_eq!("125.95 KB", format!("{adjusted_byte:.2}"));
get_appropriate_unit
方法可以被用來自動地替Byte
實體找到一個合適的單位來產生AdjustedByte
實體。
use byte_unit::{Byte, Unit, UnitType};
let byte = Byte::from_u64(1500000);
let adjusted_byte = byte.get_appropriate_unit(UnitType::Binary);
assert_eq!("1.43 MiB", format!("{adjusted_byte:.2}"));
Bit
Bit
結構體可以表示位元組的大小。
必須啟用bit
特色。
Bit
結構體的用法和Byte
結構體非常相似。也有AdjustedBit
結構體能用。有差異的地方在於Bit
的parse_str
方法不能夠設定為忽略大小寫,它總是不會忽略大小寫。
use byte_unit::{Bit, Unit};
let bit = Bit::parse_str("123Kib").unwrap();
let adjusted_bit = bit.get_adjusted_unit(Unit::Kbit);
assert_eq!("125.952 Kb", adjusted_bit.to_string());
assert_eq!("125.95 Kb", format!("{adjusted_bit:.2}"));