[C++] POCO 学習まとめ (12): ストリーム (テキストのエンコードとデコード、データ圧縮、ファイルの読み書きストリームなど)

[C++] Guo Laoer のブログ投稿: C++ ディレクトリ

1. 説明

POCO は、標準 C++ IOStream と互換性のあるさまざまなストリーム クラスを提供します。
ほとんどの POCO ストリーム クラスはフィルタとして実装されています。つまり、デバイスへの書き込みやデバイスからの読み取りではなく、接続されている別のストリームからの読み取りを行います。

2. テキストのエンコードとデコード

2.1 説明

POCO は、Base64 および HexBinary 形式でデータをエンコードおよびデコードするためのフィルター ストリーム クラスを提供します。
Base64 と HexBinary の両方を使用して、印刷可能な ASCII 文字のみを使用して任意のバイナリ データをエンコードできます。
Base64 は、数字、大文字と小文字、および「+」と「-'」を使用して 6 ビット グループをエンコードします。エンコードされたデータは、元のデータの 1.33 倍のスペースを占有します。
HexBinary は、数字と文字「A」から「F」を使用して 4 桁のグループをエンコードします。エンコードされたデータは 2 倍のスペースを占有します。

2.2 コーデック

Poco::Base64Encoder
Poco::HexBinaryEncoder
Poco::Base64Decoder
Poco::HexBinaryDecoder

#include "Poco/Base64Encoder.h"
#include <iostream>
using Poco::Base64Encoder;
int main(int argc, char** argv)
{
    
    
	Base64Encoder encoder(std::cout);
	encoder << "Hello, world!";
	return 0;
}

コンパイル:

g++ enc.cpp -I ~/git/poco/install/include -L ~/git/poco/install/lib -lPocoFoundationd

出力

SGVsbG8sIHdvcmxkIQ==

2.zlib圧縮

2.1 関連クラス

压缩:
Poco::DeftainingInputStream
Poco::DeftainingOutputStream

解決:
Poco::InflatingInputStream
Poco::InflatingOutputStream
ここに画像の説明を挿入します

2.2 例

#include "Poco/DeflatingStream.h"
#include <fstream>
using Poco::DeflatingOutputStream;
using Poco::DeflatingStreamBuf;
int main(int argc, char** argv)
{
    
    
	std::ofstream ostr("test.gz", std::ios::binary);
	DeflatingOutputStream deflater(ostr, DeflatingStreamBuf::STREAM_GZIP);
	deflater << "Hello, world!";
	// 确保在连接的流关闭之前清空缓冲区
	deflater.close();
	ostr.close();
	return 0;
}

コンパイル:

g++ zlib.cpp -I ~/git/poco/install/include -L ~/git/poco/install/lib -lPocoFoundationd

3.特殊なフロー

3.1 統計

Poco::CountingInputStream と Poco::CountingOutputStream
ファイル内の文字数と行数をカウントします。また、現在の行番号と列位置も追跡します。

3.2 改行の変換

Poco::InputLineEndingConverter および Poco::OutputLineEndingConverter
Unix (LF)、DOS/Windows (CRLF)、Mac (CR) 間で改行を変換します。

#include "Poco/LineEndingConverter.h"
#include "Poco/FileStream.h"
#include "Poco/StreamCopier.h"
#include "Poco/String.h"
#include <sstream>
#include <iostream>


using Poco::InputLineEndingConverter;
using Poco::LineEnding;
using Poco::StreamCopier;
using Poco::FileInputStream;
using Poco::FileOutputStream;
using Poco::icompare;


inline void dosToUnix(std::istream& input, std::ostream& output)
{
    
    
	InputLineEndingConverter conv(input, LineEnding::NEWLINE_LF);
	StreamCopier::copyStream(conv, output);
}


inline void unixToDos(std::istream& input, std::ostream& output)
{
    
    
	InputLineEndingConverter conv(input, LineEnding::NEWLINE_CRLF);
	StreamCopier::copyStream(conv, output);
}


inline int usage()
{
    
    
	std::cout << "Usage: LineEndingConverter {u2d | d2u} filename" << std::endl;
	return -1;
}


int main(int argc, char** argv)
{
    
    
	if (argc < 3) return usage();
	if (strlen(argv[1]) != 3) return usage();

	std::string conv(argv[1]);

	FileInputStream fis(argv[2]);
	std::stringstream ss;
	StreamCopier::copyStream(fis, ss);
	fis.close();

	FileOutputStream fos(argv[2]);
	if (0 == icompare(conv, "u2d")) unixToDos(ss, fos);
	else if (0 == icompare(conv, "d2u")) dosToUnix(ss, fos);
	else return usage();
	fos.flush();

	return 0;
}

3.3 コピーの流れ

Poco::TeeInputStream および Poco::TeeOutputStream
通過するすべての文字 (読み取りまたは書き込み) を 1 つ以上の出力ストリームにコピーします

#include "Poco/TeeStream.h"
#include <iostream>
#include <fstream>
using Poco::TeeOutputStream;
int main(int argc, char** argv)
{
    
    
	TeeOutputStream tee(std::cout);
	std::ofstream fstr("output.txt");
	tee.addStream(fstr);
	tee << "Hello, world!" << std::endl;
	return 0;
}

3.4 空の流れ

Poco::NullOutputStream: 書き込まれたすべてのデータを破棄します。
Poco::NullInputStream: 各読み取り操作のファイルの終わりを示します。

3.5 バイナリの読み取りと書き込み

Poco::BinaryWriter: 基本型の値をバイナリ形式で出力ストリームに書き込むために使用されます。
Poco::BinaryReader: バイナリ形式の読み取りに使用される基本タイプ (Poco::BinaryWriter によって生成される)

どちらも、ビッグ エンディアンおよびリトル エンディアンのバイト オーダーでの書き込みと読み取り、および自動バイト オーダー変換をサポートしています。これらのクラスは、異なるアーキテクチャのシステム間でバイナリ データを交換するのに役立ちます。

#include "Poco/BinaryWriter.h"
#include "Poco/BinaryReader.h"
#include <sstream>
#include <iostream>


using Poco::BinaryWriter;
using Poco::BinaryReader;


int main(int argc, char** argv)
{
    
    
	std::stringstream str;

	BinaryWriter writer(str);
	writer << true
	       << 'x'
	       << 42
	       << 3.14159265
	       << "foo bar";

	bool   b;
	char   c;
	int    i;
	double d;
	std::string s;

	BinaryReader reader(str);
	reader >> b
	       >> c
	       >> i
	       >> d
	       >> s;

	std::cout << b << std::endl
	          << c << std::endl
	          << i << std::endl
	          << d << std::endl
	          << s << std::endl;

	return 0;
}

4. ファイルの読み書き

POCO は、ファイルの読み取りと書き込みのためのストリーム クラスを提供します: FileStream、FileInputStream、FileOutputStream
ヘッダー ファイル: #include “Poco/FileStream.h”

Windows プラットフォームでは、ファイル ストリームに渡されるパスは UTF-8 でエンコードされます。
ファイル ストリームは常にバイナリ モードで開かれます。サポートシーク。

#include "Poco/FileStream.h"

int main(int argc, char** argv)
{
    
    
	Poco::FileStream str("test.txt", std::ios::out | std::ios::trunc);
	str << "0123456789\n";
	str << "abcdefghij\n";
	str << "klmnopqrst\n";
	str.close();

	std::string s;
	str.open("test.txt", std::ios::in);
	std::getline(str, s);
	str.close();
}

5.カスタムフロー

POCO は、カスタム ストリーム クラスの実装を簡素化するストリーム バッファ クラス テンプレートを提供します。
ストリーミングは、最初にストリーム バッファ クラス (streambuf) を作成し、次に IOS、istream、および ostream クラスを追加することによって実装されます。

利用可能なストリーム バッファー クラス テンプレートは次のとおりです。

  • Poco::BasicUnbufferedStreamBuf: は、カスタム ストリームを実装する最も簡単な方法です。
  • Poco::BasicBufferedStreamBuf: 文字型に対してインスタンス化する必要があるクラス テンプレート。
  • Poco::BasicBufferedBidirectionalStreamBuf

サブクラスは次の関数を再実装する必要があります

  • int readFromDevice(): 単一の (符号なし) バイトを読み取って返します。これ以上データが利用できない場合は、char_traits::eof()(-1) を返します。
    注: char は署名されている可能性があるため、決して char 値を直接返さないでください。文字を整数に変換するには、常に int charToInt(char c) を使用します。
  • int writeToDevice(char c): 1 バイトを書き込みます。成功した場合はバイト (整数として) を返し、それ以外の場合は char_traits::eof() (-1)

おすすめ

転載: blog.csdn.net/u010168781/article/details/134936940