RPGLE调用Java返回byte[]生成IFS PDF文件损坏问题求助
解决RPGLE调用Java生成损坏PDF的问题
你的问题核心在于错误地用字符串处理逻辑(%Trim)操作二进制PDF数据,同时固定长度CHAR变量的空格填充会写入无效数据,导致PDF文件结构损坏。以下是具体的修复方案:
1. 替换数据类型:用BLOB接收二进制数据
PDF是二进制字节流,CHAR类型即使指定CCSID(*HEX),也会在未填满时用空格(x'40')填充,写入文件时会附加无效数据。改用BLOB类型可以完美匹配Java返回的byte[]:
// 修改原型为返回BLOB类型 D GetPDF PR BLOB(16773100) ExtProc(*Java:'PDF':'get') // 定义BLOB变量接收PDF数据 Dcl-S wkPDFBlob Blob(16773100); wkPDFBlob = GetPDF();
2. 用实际字节长度写入文件
BLOB类型会自动记录有效数据的长度,直接用%Len(wkPDFBlob)获取实际大小,不要用%Trim(会破坏二进制数据中的有效空格或截断内容):
fd = open(filePath :O_CREAT + O_EXCL + O_WRONLY + O_CCSID + O_INHERITMODE :S_IRUSR :65535); // 65535表示二进制模式,不做代码页转换 write(fd: %addr(wkPDFBlob): %Len(wkPDFBlob)); // 使用实际有效长度 close(fd);
备选方案:保留CHAR类型但修正长度获取
如果必须使用CHAR类型,需要从Java端获取实际的PDF字节长度,避免依赖%Trim:
步骤1:Java端新增获取长度的方法
在PDF类中添加返回字节数组长度的方法:
public static int getPDFLength() { byte[] pdfBytes = get(); // 调用原有的get方法获取字节数组 return pdfBytes.length; }
步骤2:RPGLE中调用并使用实际长度
// 新增获取长度的原型 D GetPDFLen PR 10I 0 ExtProc(*Java:'PDF':'getPDFLength') // 原有的CHAR类型原型保留 D GetPDF PR A ExtProc(*Java:'PDF':'get') Len(16773100) CCSID(*HEX) Dcl-S pdfLen 10I 0; Dcl-S wkPDFTxt Char(16773100) CCSID(*HEX); pdfLen = GetPDFLen(); wkPDFTxt = GetPDF(); // 写入时使用实际长度,而非Trim后的长度 fd = open(filePath :O_CREAT + O_EXCL + O_WRONLY + O_CCSID + O_INHERITMODE :S_IRUSR :65535); write(fd: %addr(wkPDFTxt): pdfLen); close(fd);
额外验证
先在Java中将返回的byte[]直接写入本地文件,确认能正常打开,排除Java端生成PDF的问题。
内容的提问来源于stack exchange,提问作者user2775380
相关产品推荐
相关产品推荐

