Как программно определить CCSID файла в IFS?
У меня много файлов в IFS с различными CCSID (0, 37, 819, 1200, 1252 и т. Д.), И мне было поручено написать простую программу RPGLE [1], которая позволит пользователю просматривать содержимое любого из этих файлов.
CCSID нашей системы (V6R1) (DSPSYSVAL QCCSID) равен 65535 [2], и для наших заданий CCSID по умолчанию равен 37, что означает, что при попытке отобразить, например, CCSID 819 (ASCII), я вижу мусор - символы, случайные цвета и т. Д.
Я знаком с преобразованием данных из одного CCSID в другой через API QtqIconvOpen, поэтому, если я знаю, что файл имеет CCSID, который отличается от нашего CCSID по умолчанию, я могу преобразовать его. Я написал код несколько лет назад, чтобы сделать это, и он прекрасно работает.
Моя проблема заключается в программном обнаружении CCSID файла IFS. После поиска в Google единственная релевантная информация, которую я нашел, была здесь о Stackru от JamesA ( Как определить CCSID, используемый в команде CPYFRMIMPF?), Который указывает, что вы можете выполнить "ls -S" в QSHELL, чтобы получить список файлов, показывающих их CCSID и имя файла.
Так что теоретически я мог бы выполнить ls -S filename
проанализируйте выходные данные, чтобы получить CCSID, а затем используйте этот CCSID для выполнения преобразования данных, если это необходимо. Это ужасный хак, и я бы предпочел использовать IBM API, если это возможно.
Кто-нибудь знает такой API или более элегантный взлом, чем разбор листинга из ls -S filename
?
[1] Я использую C API open()
, read()
а также close()
сделать фактическое чтение данных.
[2] Я знаю, что 65535 - плохой выбор, но я ничего не могу с этим поделать.
3 ответа
Похоже, Qp0lGetAttr()
API "Получить атрибуты" позволит вам указать набор атрибутов для извлечения для конкретного файла, в том числе один из них называется QP0L_ATTR_CCSID
,
Вот пример использования этого API из RPG. Пример, включающий вызов Get Attr, находится в файле ZIP, связанном с этой страницей.
Вы можете использовать функцию stat() из API интегрированной файловой системы.
Определение прототипа выглядит так:
D stat PR 10I 0 ExtProc('stat')
D path * Value Options(*string)
D buf Likeds(statDS)
Тогда вам также нужна структура данных статистики:
D statDS DS Qualified Template
D st_mode 10U 0
D st_ino 10U 0
D st_nlink 5U 0
D st_reserved2 5U 0
D st_uid 10U 0
D st_gid 10U 0
D st_size 10I 0
D st_atime 10I 0
D st_mtime 10I 0
D st_ctime 10I 0
D st_dev 10U 0
D st_blksize 10U 0
D st_allocsize 10U 0
D st_objtype 11A
D st_reserved3 1A
D st_codepage 5U 0
D st_ccsid 5U 0
D st_rdev 10U 0
D st_nlink32 10U 0
D st_rdev64 20U 0
D st_dev64 20U 0
D st_reserved1 36A
D st_ino_gen_id 10U 0
использовать его довольно легко
D fileStats DS Likeds(statDS)
/free
if stat('/path/to/file': fileStats) < 0;
// error handling
endif;
// ccsid now in fileStats.st_ccsid
/end-free
Есть ли причина не использовать DSPF для этого? Утилита IBM делает отличную работу; не уверен, что вам может понадобиться.