#075
posted on 2022.06.13 (Mon) 2023.04.21 (Fri)

byte単位のファイルサイズの表記をKBやMBに変換。

任意のファイルから取得したファイルサイズのバイト数が大きい場合、桁数に応じてKBやMBに単位を変換してサイズを表示したかったので、指定した数値をJavaScriptかPHPで変換する方法のメモ。

 

「10^3 = 1000B」を「1KB」(キロバイト)とする変換方法と、「2^10 = 1024B」を「1KiB」(キビバイト)とする厳密な変換方法の両方に対応できるように実装。

キビバイト

キビバイト (kibibyte) とはコンピュータの容量や記憶装置の大きさをあらわす情報の単位の一つ。KiBと略記する。
本来SI接頭辞であり10^3を表すキロを使ったキロバイトは1,000バイトの意である。このためIECが決めた2進接頭辞を用いキビバイトとしている。この呼び名を推奨している。kibibyteとは a contraction of kilo binary byte のことである。(Wikipedia)

 

 

JavaScriptで変換処理する場合

JavaScriptで、桁数に応じてファイルサイズの表記を変換する関数を作成して、引数にファイルサイズを指定して実行する方法。

※ Mozillaのドキュメント内にあったコードを参考に作成。

 

(1) 表記を変換する関数を作成

引数で受け取った「ファイルサイズ」を、桁数に応じた単位に変換した表記にして返す関数を作成する。

  1. 引数に「処理したいファイルサイズ」、「基準のバイト数の設定(boolean値)」、「小数点の精度」を受け取るように作成。
  2. 「処理したいファイルサイズ」として渡された値が数値として扱えるかチェック。(数値に変換できない文字列の場合はエラー処理。)
  3. 「基準のバイト数」を設定。(引数に指定が無ければ、デフォルトは「false(undefined)」で「1024B = 1KiB」として計算。)
  4. 「KiB」や「MiB」などの単位を配列で保持。
  5. 変換後に表示させる数値の「小数点の精度」を設定。(引数に指定が無ければ、デフォルトは「2」で小数第3位を四捨五入して小数第2位まで表示。)
  6. 与えられた「ファイルサイズ」が「基準のバイト数」より大きければ処理を実行。(小さければ、単位を「bytes」にして結果を返す。)
  7. 計算結果が「1」より小さくなるまで「ファイルサイズ」を「基準のバイト数」で割り続ける。(割った回数が、単位の配列の中のindex位置に該当する。)
  8. 関数の返り値として、ファイルサイズの表記を変換した文字列を返す。
function ag2fileSizeOpt(a,b,c){
  let thisSize, fileUnit, thisUnit;

  //数値に変換
  thisSize = Number(a);
  //数値に変換できなかった場合
  if(isNaN(thisSize)) return 'Error : Not a Number.';
  //小数点を含めている場合
  if(String(thisSize).split('.').length > 1) return 'Error : Unaccetable Number.';

  //基準のバイト数と単位の配列を設定
  if(b){
    b = 1000;
    fileUnit = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
  }else{
    b = 1024;
    fileUnit = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
  }

  //有効小数点 デフォルト小数第2位まで(小数第3位で四捨五入)
  if(c !== 0){c = c ? c : 2;}

  if(thisSize >= b){
    for(let i = 0, j = 0, sizeTemp = (thisSize / b); sizeTemp >= 1 && j < fileUnit.length; i++, j++, sizeTemp /= b){
      thisUnit = i;
      thisSize = sizeTemp;
    }
    thisSize = (Math.round(thisSize * (10**c))/(10**c))+' '+fileUnit[thisUnit]+' ('+a+' bytes)';
  }else{
    if(a === 1) thisUnit = 'byte';
    else thisUnit = 'bytes';
    thisSize = a+' '+thisUnit;
  }

  //変換した表記の文字列を返す
  return thisSize;
}

 

(2) 関数の実行

上述で作成した関数を任意の場所で実行する。

JavaScriptでは、「Number.MAX_SAFE_INTEGER」である「9007199254740991」を超える数値だと誤差が発生してしまうので、結果の精度を担保したい場合は数値ではなく必ず文字列の状態で引数に指定する。

※ JavaScriptの数値には「IEEE 754」の規格が採用されているため、「9007199254740991」より大きな数値は勝手に丸められるので、下数桁の精度が保証されない。

let thisFileSize = ag2fileSizeOpt('123456789');
console.log(thisFileSize);
//出力されるコンソールの内容
//117.74 MiB (123456789 bytes)

let thisFileSize = ag2fileSizeOpt('123456789123456789');
console.log(thisFileSize);
//出力されるコンソールの内容
//109.65 PiB (123456789123456789 bytes)

let thisFileSize = ag2fileSizeOpt('123456789',true,1);
console.log(thisFileSize);
//出力されるコンソールの内容
//123.5 MB (123456789 bytes)

let thisFileSize = ag2fileSizeOpt('123456789123456789',true,1);
console.log(thisFileSize);
//出力されるコンソールの内容
//123.5 PB (123456789123456789 bytes)

//JavaScriptでは15桁を超えた数値は勝手に丸まる
let thisFileSize = ag2fileSizeOpt(123456789123456789,true);
console.log(thisFileSize);
//出力されるコンソールの内容
//123.46 PB (123456789123456780 bytes)

 

 

PHPで変換処理する場合

PHPで、ファイルサイズの表記を変換する関数を作成して、引数にファイルサイズを指定して実行する方法。

 

(1) 表記を変換する関数を作成

引数で受け取った「ファイルサイズ」を、桁数に応じた単位に変換した表記にして返す関数を作成する。

  1. 引数に「処理したいファイルサイズ」、「基準のバイト数の設定(boolean値)」、「小数点の精度」を受け取るように作成。
  2. 「処理したいファイルサイズ」として渡された値が数値として扱えるかチェック。(数値に変換できない文字列の場合はエラー処理。)
  3. 「基準のバイト数」を設定。(引数に指定が無ければ、デフォルトは「false(undefined)」で「1024B = 1KiB」として計算。)
  4. 「KiB」や「MiB」などの単位を配列で保持。
  5. 変換後に表示させる数値の「小数点の精度」を設定。(引数に指定が無ければ、デフォルトは「2」で小数第3位を四捨五入して小数第2位まで表示。)
  6. 与えられた「ファイルサイズ」が「基準のバイト数」より大きければ処理を実行。(小さければ、単位を「bytes」にして結果を返す。)
  7. 計算結果が「1」より小さくなるまで「ファイルサイズ」を「基準のバイト数」で割り続ける。(割った回数が、単位の配列の中のindex位置に該当する。)
  8. 関数の返り値として、ファイルサイズの表記を変換した文字列を返す。
function ag2file_size_opt($filesize, $kiro=false, $point=2){
  //値が数値か確認
  if(!is_numeric($filesize)) return 'Error : Not a Number.';
  //小数点を含めている場合
  if(preg_match('/[.]/', $filesize)) return 'Error : Unaccetable Number.';

  //基準のバイト数と単位の配列を設定
  if($kiro){
    $kiro = 1000;
    $file_unit = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
  }else{
    $kiro = 1024;
    $file_unit = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
  }
  $file_unit_num = count($file_unit);

  if($filesize >= $kiro){
    for($i = 0, $j = 0, $size_temp = ($filesize / $kiro); $size_temp >= 1 && $j < $file_unit_num; $i++, $j++, $size_temp /= $kiro){
      $this_unit = $i;
      $this_size = $size_temp;
    }
    $this_size = (round($this_size, $point)).' '.$file_unit[$this_unit].' ('.$filesize.' bytes)';
  }else{
    if($filesize === 1) $this_unit = 'byte';
    else $this_unit = 'bytes';
    $this_size = $filesize.' '.$this_unit;
  }

  //変換した表記の文字列を返す
  return $this_size;
}

 

(2) 関数の実行

上述で作成した関数を任意の場所で実行して出力する。

echo ag2file_size_opt(123456789);
//出力結果
//117.74 MiB (123456789 bytes)

echo ag2file_size_opt(123456789123456789);
//出力結果
//109.65 PiB (123456789123456789 bytes)

echo ag2file_size_opt(123456789,ture,1);
//出力結果
//123.5 MB (123456789 bytes)

 

 

この記事のURL

https://memo.ag2works.tokyo/post-4649/

Copyコピー
この記事のタイトル

byte単位のファイルサイズの表記をKBやMBに変換。 | memo メモ [AG2WORKS]

Copyコピー
この記事のリンクタグ

<a href="https://memo.ag2works.tokyo/post-4649/" target="_blank" rel="noopener">byte単位のファイルサイズの表記をKBやMBに変換。 | memo メモ [AG2WORKS]</a>

Copyコピー
※ フィールドをクリックでコピーするテキストの編集ができます。

この記事へのコメント

コメントの書き込みはまだありません。

  • コメント内のタグはエスケープ処理され、文字列として出力されます。
  • セキュリティーのため、投稿者のIPアドレスは取得されます。
  • 管理者が内容を不適切と判断したコメントは削除されます。
  • このフォームにはスパム対策として、Googleの提供するreCAPTCHAシステムが導入されています。
    (Google Privacy Policy and Terms of Service.)