2022.12.27

Apexでのファイル読み込み時の文字コードについて

はじめに

今回の内容は、SalesforceのApexでファイル読み込む時の文字コード対応についてです。
会社間や部署間のファイル連携に、Salesforceの「ファイル」機能を使用する際、他システムで出力されたファイルの中には、Salesforceの使用する 「UTF-8」以外の文字コード で保存されたファイルも含まれます。そうした文字コードのファイルを読み込む時の処理の一例を紹介します。

ファイル機能による連携イメージ

まず、Salesforce「ファイル」機能を使用した連携イメージは以下となります。

・CSVファイルは業務用途ごと作成したライブラリ配下に格納する
・CSVファイルには以下のものがある
  -  SalesforceオブジェクトのレコードをもとにApexで出力するもの
  -  他システムで出力し、手動で格納するもの
  -  「UTF-8」でない文字コードで保存されたもの

Apexでのファイルデータ読み込み処理

文字コードがUTF-8の場合

文字コードがUTF-8のファイルデータを読み込む場合、Blob.toString()メソッド でBlobから文字列に変換できます。
// ContentVersionオブジェクトよりCSVファイルのデータを取得する
ContentVersion cv = [SELECT Id,Title,VersionData FROM ContentVersion WHERE Title = 'Sample' AND IsLatest = true];

// 保存CSVファイルのデータ(Blob)
Blob csvBlob = cv.VersionData;

// Blobから文字列に変換
String csvStr = csvBlob.toString();
※Apexサンプルコード(UTF-8の場合)
しかし、文字コードがUTF-8でない場合、上記サンプルコードの csvBlob.toString() の箇所でエラー 「BLOB is not a valid UTF-8 string」 が発生します。
では、次に文字コードがUTF-8でない場合をみていきましょう。

文字コードがUTF-8でない場合

UTF-8でない場合は、上記サンプルコードの csvBlob.toString() の箇所で、URLエンコード・デコード​処理を行う ことでBlobから文字列に変換することができます。
たとえばファイルの文字コードがUTF-16の場合は以下のようになります。
//  (1) Blobから16進数文字列(Hex)に変換
String hex = EncodingUtil.convertToHex(csvBlob);
;
//  (2) 16進数文字列(Hex)の2桁ごとに%を付与する
String encodeStr = '';
for(Integer i = 0; i < hex.length(); i += 2) {
    encodeStr += '%' + hex.mid(i, 2);
}

//  (3) ファイルの文字エンコード方式でデコード ※例:UTF-16
String csvStr  = EncodingUtil.urlDecode(encodeStr, 'UTF-16');
※Apexサンプルコード(UTF-16の場合)
URLエンコードは、文字コードを16進数文字列にし、2桁ごとに%を付与した形式に変換する 処理となり、上記サンプルコードの(1) (2) に該当します。
ApexにははURLエンコードを行う EncodingUtil.urlEncode(inputString, encodingScheme) ​メソッド がありますが、このメソッドは引数に文字列をとるもので、Blobからの変換には使用できないため、上記サンプルコードのように自前で実装することになります。

※サンプルコード(1) (3)で使用の以下2メソッドもEncodingUtilクラスにありますので、あわせて​ご確認ください。
 ・convertToHex(inputBlob)
 ・urlDecode(inputString, encodingScheme)

なお、上記サンプルコードの処理はUTF-16だけでなく、他の文字コードでも適用可能です。
下表に「商品」という文字列を例とした変換結果を示しています。
文字コード(エンコード方式) UTF-16 UTF-8 Shift_JIS
(1) Blobから16進数文字列に変換 554654c1 e59586e59381 8fa49569
(2) 2桁ごとに%付与 %55%46%54%c1 %e5%95%86%e5%93%81 %8f%a4%95%69
(3) デコード 商品 商品 商品
文字コード(エンコード方式)により、バイナリ値が異なるため、16進数文字列への変換結果もそれぞれ異なりますが、いずれの場合においても「商品」という文字列が得られます。

まとめ

今回は、Apexにおける文字コード対応の一例を紹介しました。
文字コードは、奥が深くとっつきにくいイメージもあるかもしれませんが、システム開発・運用において必ず必要になるため、理解を深めておきたい知識ではないでしょうか。
また、Salesforceの「ファイル」機能については、過去の記事 Salesforceの「ファイル」を使ってみようで詳しく紹介されていますので、ぜひ参考にしてみてください。
20 件
     
  • banner
  • banner

関連する記事