如何在IBM i的ILE C++中用std::ofstream打开打印机文件?
在ILE C++中使用ofstream打开IBM i打印机文件的方法
不能直接使用std::ofstream打开IBM i的打印机文件。标准C++的fstream类是为POSIX兼容的文件系统设计的,而IBM i的打印机文件(*FILE类型的子类)属于系统特有的假脱机输出对象,并非常规可通过POSIX流访问的文件。
为什么你的尝试失败
你之前的几种写法都无法正确访问打印机文件:
std::ofstream stream("QSYSPRT"):标准流默认在当前POSIX工作目录(通常是/home/<user>)创建普通文本文件,而非访问IBM i原生库中的打印机文件。*LIBL/QSYSPRT或/QSYS.LIB/QSYSPRT.FILE:QSYS.LIB下的*FILE对象是IBM i原生对象,不兼容POSIX文件系统的访问方式,标准流无法识别。
正确实现方式
要在ILE C++中操作打印机文件,需要结合ILE C的扩展功能或IBM i系统API,以下是两种可行方案:
方案1:用ILE C的fopen打开打印机文件,关联到C++流
ILE C的fopen支持第三个参数,用于指定IBM i特定的文件属性,可直接打开打印机文件,之后将其关联到C++的ofstream:
#include <fstream> #include <cstdio> #include <cerrno> int main() { // 使用ILE C扩展打开打印机文件,第三个参数"QPRT"表示打印机文件类型 FILE* prt_fp = fopen("*LIBL/QSYSPRT", "w", "QPRT"); if (!prt_fp) { perror("Failed to open printer file"); return 1; } // 将FILE*转换为文件描述符,关联到std::ofstream int fd = fileno(prt_fp); std::ofstream prt_stream(fd); // 向打印机文件输出内容 prt_stream << "ILE C++ 打印机文件测试输出" << std::endl; prt_stream << "多行测试内容" << std::endl; // 关闭资源:先关闭C++流,再关闭FILE* prt_stream.close(); fclose(prt_fp); return 0; }
方案2:调用IBM i系统API操作假脱机文件
直接使用IBM i的假脱机服务API(如QSPOPEN、QSPPUT、QSPCLSE)来创建和写入假脱机文件,这种方式更灵活,可控制更多打印机属性:
#include <iostream> #include <cstring> // 包含假脱机服务API的头文件 #include <qsppopen.h> #include <qsppput.h> #include <qspclse.h> int main() { char spool_handle[10] = {0}; int rc; // 初始化QSPOPEN参数,指定打印机文件和库 QSPOPEN_PARM open_parms = {0}; strncpy(open_parms.printer_file_name, "QSYSPRT", 10); strncpy(open_parms.library_name, "*LIBL", 10); open_parms.spool_file_handle = spool_handle; // 打开打印机文件,获取假脱机句柄 rc = QSPOPEN(&open_parms, sizeof(open_parms)); if (rc != 0) { std::cerr << "QSPOPEN调用失败,返回码:" << rc << std::endl; return 1; } // 写入内容到假脱机文件 const char* output_content = "API方式测试打印机文件输出\n第二行内容"; QSPPUT_PARM put_parms = {0}; strncpy(put_parms.spool_file_handle, spool_handle, 10); put_parms.data_buffer = (char*)output_content; put_parms.data_length = strlen(output_content); rc = QSPPUT(&put_parms, sizeof(put_parms)); if (rc != 0) { std::cerr << "QSPPUT调用失败,返回码:" << rc << std::endl; QSPCLSE(spool_handle); // 出错时关闭句柄 return 1; } // 关闭假脱机文件句柄 rc = QSPCLSE(spool_handle); if (rc != 0) { std::cerr << "QSPCLSE调用失败,返回码:" << rc << std::endl; return 1; } return 0; }
注意事项
- 编译时需确保使用ILE C++编译器(如
CRTCPPMOD或CRTPGM命令),并链接必要的系统服务库。 - 若需要控制打印机的具体属性(如输出队列、页大小),可在
fopen的第三个参数中添加更多选项,或在API参数中指定。
内容的提问来源于stack exchange,提问作者Chris Charlton
相关产品推荐
相关产品推荐

