POCO C++库学习和分析 -- 流 (一)

POCO C++库学习和分析 -- 流 (一)



          流(Stream)是C++和C之间的一大区别。写C++的程序员都知道流的用法。在Poco库中,在标准流的基础上又扩充了一些流,分别是基于Base64和HexBinary的编解码流,使用zlib的数据压缩流,二进制的I/O流,文件流,以及一些其他的辅助流;另外Poco库还提供了一个扩展的结构,用于创建用户自定义流。

          Poco库中所有的流类都与标准c++库中的流兼容。并且在Poco库中,大多数流都仅仅是个过滤器,这意味着它们不会直接从设备中读取或者写入数据,通常情况下它们会链接到另一个流上。下面我们分别对它们进行介绍。


1. 标准c++流介绍

          在介绍Poco的流之前,我觉得有必要了解C++中的输入输出流,不然就会觉得Poco中的流很难理解。在看完C++的流结构后,自然会对Poco库中的流内容豁然开朗。我也一样。
          为了保证语言和平台无关,C++和C一样,不具备内部输入输出能力。语言的输入输出能力是和操作系统相关的,在最底层都是通过调用操作系统的I/O库实现。

          在C++的iostream流库中,存在着两个基本部分。分别是:
          1. 流:C++把输入和输出看作字节流。输入时,程序从输出流中抽取字节;输出时,程序将字节插入到输出流中。流充当了程序和流源或者流目标之间的桥梁。
          2. 缓冲区:缓冲区是用作中介的内存块,它是将信息从设备传输到程序或者从程序传输到设备的临时存储工具,用以匹配程序和设备之间速度的差距。从设计上说,增加了缓冲区,使的C++的iostream结构更具有扩展性。

          C++的 输入输出类图



          下面对C++中各个流类的介绍主要来自于wiki以及网站 cplusplus


1.1 ios_base

          ios_base类封装了C++标准中的流,并定义了在输入输出中不依赖于读写的数据类型的基本信息和行为,如格式化信息、异常状态、事件回调等。

          在类std::ios_base中,保存了下述关于流的信息:
          格式控制信息的枚举类型fmtflags ,影响到如何解释输入串行的格式、如何生成输出串行的格式,例如整数是用16进制还是10进制表示,浮点数是科学计数法还是定点形式;
          流的状态枚举类型iostate,如数据是否完整、是否到达流的末尾、是否读写失败等;
          流的打开方式枚举类型openmode,如读取、写入、追加、创建时删除原内容、二进制打开、
          流的定位位置枚举类型seekdir,如开始位置、当前位置、结尾位置等。
          流的事件枚举类型event,如“擦除”事件erase_event,改变locale设置事件imbue_event,复制格式事件copyfmt_event。
          流的私有的其它额外保存的数据,为一个long型数组与一个指针数组。
          一个成员类failure,用于作为C++标准中,流输入输出类库抛出的各种异常的基类。
          一个成员类Init,用于封装cout、cin、wcout等8个静态对象的初始化函数。

          成员函数包括:

          格式化:

          1. 读取/设置流的格式

fmtflags flags() const;
fmtflags flags (fmtflags fmtfl);
  例子:
// modify flags
#include <iostream>     // std::cout, std::ios

int main () {
  std::cout.flags ( std::ios::right | std::ios::hex | std::ios::showbase );
  std::cout.width (10);
  std::cout << 100 << '\n';
  return 0;
}


          2. 设置流的格式,与原有格式合并
fmtflags setf (fmtflags fmtfl);
fmtflags setf (fmtflags fmtfl, fmtflags mask);
  例子:
// modifying flags with setf/unsetf
#include <iostream>     // std::cout, std::ios

int main () {
  std::cout.setf ( std::ios::hex, std::ios::basefield );  // set hex as the basefield
  std::cout.setf ( std::ios::showbase );                  // activate showbase
  std::cout << 100 << '\n';
  std::cout.unsetf ( std::ios::showbase );                // deactivate showbase
  std::cout << 100 << '\n';
  return 0;
}
输出:
         Output:
         0x64
         64


          3. 根据参数mask,清除流的格式的某些位(bit)
void unsetf (fmtflags mask);
  例子:
// modifying flags with setf/unsetf
#include <iostream>     // std::cout, std::ios

int main () {
  std::cout.setf ( std::ios::hex, std::ios::basefield );  // set hex as the basefield
  std::cout.setf ( std::ios::showbase );                  // activate showbase
  std::cout << 100 << '\n';
  std::cout.unsetf ( std::ios::showbase );                // deactivate showbase
  std::cout << 100 << '\n';
  return 0;
}
输出:
         0x64
         64


          4. 读取/设置显示浮点数时的精度
streamsize precision() const;
streamsize precision (streamsize prec);
  例子:
// modify precision
#include <iostream>     // std::cout, std::ios

int main () {
  double f = 3.14159;
  std::cout.unsetf ( std::ios::floatfield );                // floatfield not set
  std::cout.precision(5);
  std::cout << f << '\n';
  std::cout.precision(10);
  std::cout << f << '\n';
  std::cout.setf( std::ios::fixed, std:: ios::floatfield ); // floatfield set to fixed
  std::cout << f << '\n';
  return 0;
}
输出:
         3.1416
         3.14159
         3.1415900000


          5. 读取/设定流的输出数据的显示宽度
streamsize width() const;
streamsize width (streamsize wide);
  例子:
// field width
#include <iostream>     // std::cout, std::left

int main () {
  std::cout << 100 << '\n';
  std::cout.width(10);
  std::cout << 100 << '\n';
  std::cout.fill('x');
  std::cout.width(15);
  std::cout << std::left << 100 << '\n';
  return 0;
}
输出:
         100
                100
         100xxxxxxxxxxxx


           语言环境:
          1. 给流设置本地语言环境
locale imbue (const locale& loc);
  例子:
// imbue example
#include <iostream>     // std::cout
#include <locale>       // std::locale

int main()
{
  std::locale mylocale("");   // get global locale
  std::cout.imbue(mylocale);  // imbue global locale
  std::cout << 3.14159 << '\n';
  return 0;
}

输出:

         3,14159


          2. 获取当前使用语言环境
locale getloc() const;

1.2 basic_ios

          basic_ios定义出“与字符类型及其相应字符特性相关”的stream class的共同属性,其中包括清除流状态、设置流状态、拷贝流标志、返回或设置流缓冲区指针、设置本地化相关信息、返回或设置填充字符、字符转换,还包括了stream所用的缓冲器.
          basic_ios在其内部定义了一个指向streambuf的指针。
template <class Elem, class Traits>
class basic_ios
     : public ios_base
{
     //C++标准库封装了一个缓冲区类streambuf,以供输入输出流对象使用。
     //每个标准C++输出输出流对象都包含一个指向streambuf的指针,
     basic_streambuf<_Elem, _Traits>*_Mystrbuf;


     // ....
}


           成员函数包括:

         1. 状态标记函数:
bool good() const; //检查流状态位是否为good
bool eof() const; //检查流状态位是否为eof,eofbit位被标志
bool fail() const; //检查流状态位是否为fail,failbit或者badbit被标志
bool bad() const; //检查流状态位是否为bad,badbit位被标志
iostate rdstate() const; //返回流状态位

          有两种方法可以获得输入/输出的状态信息。一种方法是通过调用rdstate()函数,它返回当前状态的错误标记。另一种方法则是使用good(), eof(),fail(), bad()函数来检测相应的输入/输出状态。
          状态位和函数返回值关系如下表:


iostate value
(member constant)
indicates functions to check state flags
good() eof() fail() bad() rdstate()
goodbit No errors (zero value iostate) true false false false goodbit
eofbit End-of-File reached on input operation false true false false eofbit
failbit Logical error on i/o operation false false true false failbit
badbit Read/writing error on i/o operation false false true true badbit


         例子:

// error state flags
#include <iostream>     // std::cout, std::ios
#include <sstream>      // std::stringstream

void print_state (const std::ios& stream) {
  std::cout << " good()=" << stream.good();
  std::cout << " eof()=" << stream.eof();
  std::cout << " fail()=" << stream.fail();
  std::cout << " bad()=" << stream.bad();
}

int main () {
  std::stringstream stream;

  stream.clear (stream.goodbit);
  std::cout << "goodbit:"; print_state(stream); std::cout << '\n';

  stream.clear (stream.eofbit);
  std::cout << " eofbit:"; print_state(stream); std::cout << '\n';

  stream.clear (stream.failbit);
  std::cout << "failbit:"; print_state(stream); std::cout << '\n';

  stream.clear (stream.badbit);
  std::cout << " badbit:"; print_state(stream); std::cout << '\n';

  return 0;
}
输出:
         goodbit: good()=1 eof()=0 fail()=0 bad()=0
         eofbit: good()=0 eof()=1 fail()=0 bad()=0
         failbit: good()=0 eof()=0 fail()=1 bad()=0
         badbit: good()=1 eof()=0 fail()=1 bad()=1


         2. oprator!()
bool operator!() const;
         如果没有错误标记被设置(failbit或badbit),返回true,否则返回false


         3. 设置/清除状态
void setstate (iostate state);
void clear (iostate state = goodbit);
         有两种方法可以设置输入/输出的状态信息。clear()函数可以使流状态将按照ios_base::iostate所描述的样子进行设置。ios::failbit、ios::badbit、ios::eofbit、ios::goodbit均为常量,它们中的任何一个都代表了一种流状态,或可被称为“输入状态标记位常量”。它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量。标记为常量的状态如上表所述。

         clear() 函数作用是:将流状态设置成括号内参数所代表的状态,强制覆盖掉流的原状态。

         例子:

// clearing errors
#include <iostream>     // std::cout
#include <fstream>      // std::fstream

int main () {
  char buffer [80];
  std::fstream myfile;

  myfile.open ("test.txt",std::fstream::in);

  myfile << "test";
  if (myfile.fail())
  {
    std::cout << "Error writing to test.txt\n";
    myfile.clear();
  }

  myfile.getline (buffer,80);
  std::cout << buffer << " successfully read from file.\n";

  return 0;
}

         setstate()函数的作用是:它并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。它相当于:
void basic_ios::setstate (iostate state) {
  clear(rdstate()|state);
}


         4. 拷贝格式:
basic_ios& copyfmt (const basic_ios& rhs);

         例子:
// copying formatting information
#include <iostream>     // std::cout
#include <fstream>      // std::ofstream

int main () {
  std::ofstream filestr;
  filestr.open ("test.txt");

  std::cout.fill ('*');
  std::cout.width (10);
  filestr.copyfmt (std::cout);

  std::cout << 40;
  filestr << 40;

  return 0;
}


         5. 设置或获取填充字符
char_type fill() const;
char_type fill (char_type fillch);

         例子:
// using the fill character
#include <iostream>     // std::cout

int main () {
  char prev;

  std::cout.width (10);
  std::cout << 40 << '\n';

  prev = std::cout.fill ('x');
  std::cout.width (10);
  std::cout << 40 << '\n';

  std::cout.fill(prev);

  return 0;
}
输出:
                 40
         xxxxxxxx40


         6. 返回和设置当前流的异常标志
iostate exceptions() const;
void exceptions (iostate except);

         例子:
// basic_ios::exceptions
#include <iostream>     // std::cerr
#include <fstream&
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会为您解析 Poco C++网络模块的 HttpServer 示例。 HttpServer 是一个用于创建 HTTP 服务器的类,可以用于处理 HTTP 请求和响应。下面是一个简单的 HttpServer 示例,它监听来自客户端的请求并返回一个简单的响应: ```cpp #include "Poco/Net/HTTPServer.h" #include "Poco/Net/ServerSocket.h" #include "Poco/Util/ServerApplication.h" #include "Poco/Net/HTTPRequestHandlerFactory.h" #include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Net/HTTPServerResponse.h" #include <iostream> using namespace Poco::Net; using namespace Poco::Util; using namespace std; class MyRequestHandler: public HTTPRequestHandler { public: void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { response.setChunkedTransferEncoding(true); response.setContentType("text/html"); ostream& ostr = response.send(); ostr << "<html><head><title>My 1st HTTP Server</title></head>"; ostr << "<body><h1>Hello, world!</h1></body></html>"; } }; class MyRequestHandlerFactory: public HTTPRequestHandlerFactory { public: HTTPRequestHandler* createRequestHandler(const HTTPServerRequest&) { return new MyRequestHandler; } }; class MyServerApp: public ServerApplication { protected: int main(const vector<string>&) { HTTPServer server(new MyRequestHandlerFactory, ServerSocket(8080), new HTTPServerParams); server.start(); cout << "Server started" << endl; waitForTerminationRequest(); server.stop(); cout << "Server stopped" << endl; return Application::EXIT_OK; } }; int main(int argc, char** argv) { MyServerApp app; return app.run(argc, argv); } ``` 在这个示例中,我们定义了一个 MyRequestHandler 类来处理 HTTP 请求。这个类只有一个方法 handleRequest,它接收 HTTPServerRequest 对象和 HTTPServerResponse 对象作为参数。 handleRequest 方法设置 HTTP 响应的头信息,然后通过 HTTPServerResponse 对象发送响应的正文。代码中发送的响应正文是一个简单的 HTML 页面,其中包含一个标题和一个“Hello, world!”的消息。 MyRequestHandlerFactory 类是一个工厂类,它实现了 HTTPRequestHandlerFactory 接口。当服务器接收到一个新的请求时,它调用 MyRequestHandlerFactory 的 createRequestHandler 方法来创建一个新的 MyRequestHandler 对象来处理该请求。 MyServerApp 类继承了 ServerApplication 类,它用于启动和停止 HTTP 服务器。在 main 方法中,我们创建了一个 HTTPServer 对象,并将 MyRequestHandlerFactory、ServerSocket 和 HTTPServerParams 对象传递给它。然后,我们调用 HTTPServer 对象的 start 方法来启动服务器,并调用 waitForTerminationRequest 方法来等待服务器终止请求。最后,我们调用 HTTPServer 对象的 stop 方法来停止服务器。 这就是 Poco C++网络模块中的 HttpServer 示例的解析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值