[解決済み] バイナリファイルを符号なし文字列のベクトルに読み込む方法
質問
最近、バイナリファイルを読み込んで
std::vector<BYTE>
ここで
BYTE
は
unsigned char
. すぐにこんな感じになりました。
#include <fstream>
#include <vector>
typedef unsigned char BYTE;
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::streampos fileSize;
std::ifstream file(filename, std::ios::binary);
// get its size:
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// read the data:
std::vector<BYTE> fileData(fileSize);
file.read((char*) &fileData[0], fileSize);
return fileData;
}
への明示的なキャストは不必要に複雑に見えます。
char*
を呼び出す際に使わざるを得なかった
file.read
を呼び出したところで、何の気分転換にもならない。
別の方法として
std::istreambuf_iterator
:
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::ifstream file(filename, std::ios::binary);
// read the data:
return std::vector<BYTE>((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
}
というように、かなりシンプルで短いものですが、やはり
std::istreambuf_iterator<char>
に読み込んでいるときでも
std::vector<unsigned char>
.
完全に分かりやすいと思われる最後のオプションは
std::basic_ifstream<BYTE>
と明示的に表現することです。
入力ファイルストリームが必要で、それを使って
BYTE
s"
:
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::basic_ifstream<BYTE> file(filename, std::ios::binary);
// read the data:
return std::vector<BYTE>((std::istreambuf_iterator<BYTE>(file)),
std::istreambuf_iterator<BYTE>());
}
というのがありますが
basic_ifstream
がこの場合適切な選択かどうかはわかりません。
にバイナリファイルを読み込む最良の方法は何でしょうか?
vector
?
また、私は何が起こっているのかを知りたいのです。
。
と、私が遭遇する可能性のある問題は何か(ストリームが正しく開かれないことは別として、これは単純な
is_open
のチェックで回避できるかもしれません)。
を使用することを好む正当な理由はありますか?
std::istreambuf_iterator
を使うべき理由はありますか?
(私が見ることができる唯一の利点は、シンプルであることです)
どのように解決するのですか?
パフォーマンスに関するテストを行う場合、私は以下のようなテストケースを含めます。
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::ifstream file(filename, std::ios::binary);
// Stop eating new lines in binary mode!!!
file.unsetf(std::ios::skipws);
// get its size:
std::streampos fileSize;
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// reserve capacity
std::vector<BYTE> vec;
vec.reserve(fileSize);
// read the data:
vec.insert(vec.begin(),
std::istream_iterator<BYTE>(file),
std::istream_iterator<BYTE>());
return vec;
}
私の考えでは、方法1のコンストラクタで
vector
の要素に触れ、その後に
read
は再び各要素に触れる。
方法 2 と方法 3 は最も有望に見えますが、1 つまたは複数の
resize
's. そのため
reserve
を挿入してください。
私はまた、テストするために
std::copy
:
...
std::vector<byte> vec;
vec.reserve(fileSize);
std::copy(std::istream_iterator<BYTE>(file),
std::istream_iterator<BYTE>(),
std::back_inserter(vec));
結局のところ、最適解は
operator >>
から
istream_iterator
(からのオーバーヘッドと良さは、すべて
operator >>
はバイナリデータを解釈しようとしている)。しかし、データを直接ベクターにコピーできるようなものを使うのはどうなんでしょう。
最後に、バイナリデータを使った私のテストでは
ios::binary
は尊重されないことがわかりました。そのため
noskipws
から
<iomanip>
.
関連
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Git リポジトリで削除されたファイルを検索して復元する方法
-
[解決済み] Pythonでファイルやフォルダを削除する方法は?
-
[解決済み] Microsoft Officeをインストールせずに、C#でExcel(.XLSおよび.XLSX)ファイルを作成するにはどうすればよいですか?
-
[解決済み] ファイルの内容からJavaの文字列を作成するにはどうすればよいですか?
-
[解決済み] ファイルを作成し、書き込むにはどうすればよいですか?
-
[解決済み] C++でifstreamを使用してファイルを一行ずつ読み込む
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】coutはstdのメンバではない
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] C++でファイルをベクターに読み込むには?