Как программно определить 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 делает отличную работу; не уверен, что вам может понадобиться.

Другие вопросы по тегам