Se você já tentou usar programas baseados no POSIX para processar arquivos estruturados VOS, você pode ter encontrado algumas restrições ou visto algum comportamento que você não entendeu. Neste post eu tentarei explicar o que está acontecendo.
O VOS suporta 4 tipos de arquivos: seqüenciais, relativos, fixos e de fluxo. Os 3 primeiros formatos são chamados de arquivos "estruturados" porque o sistema de arquivos mantém o controle dos limites dos registros. As operações de E/S disponíveis lêem e escrevem registros inteiros. O último formato é chamado de "não estruturado" porque os limites dos registros estão implícitos; o novo caractere de linha delimita os registros. As operações de E/S disponíveis lêem e escrevem seqüências de bytes.
Um ambiente compatível com POSIX, tal como encontrado em um sistema Unix® ou Linux©, tem apenas um tipo de arquivo nativo, que é chamado de "arquivo normal". A organização do arquivo VOS stream é equivalente a um arquivo POSIX regular.
O ambiente de execução VOS POSIX classifica todos os 4 tipos de arquivos como arquivos regulares POSIX. Assim, pelo menos em teoria, qualquer programa POSIX pode ler ou escrever qualquer um dos 4 tipos de arquivo. Entretanto, não é tão simples assim.
Como o POSIX API define todas as operações de E/S em termos de seqüências de bytes, enquanto o VOS define as operações de E/S (em arquivos estruturados) em termos de seqüências de registros, o VOS POSIX mede a diferença através do buffer do registro atual no espaço do usuário, realizando as operações de E/S do POSIX no buffer e, em seguida, escrevendo o registro buffer de volta nos pontos apropriados.
Se o programa POSIX souber o tamanho de cada registro (digamos, para um arquivo fixo), e se ele ler e escrever o número exato de bytes, então a presença do buffer não afeta a operação, e o mapeamento dos dois tipos de operações de E/S é fácil de entender e eficiente.
Mas se o programa POSIX está apenas lendo ou escrevendo um fluxo de bytes sem considerar o tamanho do registro subjacente, então o mapeamento da semântica POSIX para a semântica VOS, embora bem definido, não é geralmente muito útil, e é freqüentemente bastante ineficiente. Algumas operações, como a busca de uma posição de bytes, ou a reescrita de uma seqüência de bytes que se estende através de um limite de registro, são ineficientes na melhor das hipóteses e impossíveis na pior das hipóteses.
Depois há a questão do manuseio dos caracteres da nova linha.
Tanto um arquivo POSIX regular quanto um arquivo VOS stream utilizam o novo caractere de linha para distinguir um limite de registro. No entanto, os registros VOS em arquivos estruturados normalmente não contêm nenhum caractere de nova linha. Por exemplo, quando um editor VOS (por exemplo, editar, emacs ou line_edit) cria um novo arquivo seqüencial, cada registro contém uma linha de texto. Mas o registro não termina em um novo caractere de linha. Por convenção, todos os programas assumem que um arquivo seqüencial que contém texto tem uma nova linha implícita no final de cada registro. O mesmo se aplica aos arquivos relativos e fixos. Mas aqui está um ponto importante: nenhum atributo de qualquer arquivo (VOS, Unix, estruturado ou não estruturado) registra se o arquivo contém texto ou dados binários. A distinção é deixada para os programas que acessam o arquivo.
Esta situação cria uma espécie de quandry para o tempo de execução do VOS POSIX. É preciso saber se um arquivo estruturado VOS contém texto ou dados para saber se deve ou não anexar uma nova linha a cada registro. Se o arquivo contiver texto, ele deve anexar uma nova linha. Se ele contém dados, não deve anexar uma nova linha.
A resposta é que o tempo de execução do VOS POSIX depende do autor da chamada para fornecer esta informação. Por padrão, o tempo de execução POSIX trata os arquivos estruturados como se eles contivessem texto, e anexa uma nova linha; um chamador pode solicitar explicitamente este comportamento, fornecendo o modo de abertura O_TEXT. Um chamador que deseja tratar um arquivo estruturado VOS como contendo dados deve fornecer o modo de abertura O_BINÁRIO. Estes dois modos são mutuamente exclusivos; se você especificar um deles, você não deve especificar o outro. Estes modos não são necessários para os arquivos stream, e por isso são ignorados neste caso.
Para os advogados que estão lendo este post, deixe-me rapidamente notar que tanto O_TEXT quanto O_BINÁRIO são extensões do padrão POSIX; eles não são definidos pelo próprio POSIX. Eles normalmente só estão presentes em sistemas operacionais que distinguem entre arquivos de texto e binários (como o VOS), ou têm uma convenção especial de fim de linha (como o Windows; usando CR-LF).
Por política, quando o Stratus porta software POSIX para o OpenVOS, nós o modificamos para excluir o uso de arquivos FIXED e RELATIVE, e restringimos os arquivos SEQUENTIAL para acesso somente leitura. Também assumimos que todos os arquivos seqüenciais contenham texto. Em nossa experiência, estas regras tornam prático o uso de arquivos STREAM ou SEQUENTIAL como entrada para programas POSIX, evitando as ineficiências inerentes de tentar realizar operações orientadas a bytes nos arquivos de saída SEQUENTIAL.
Em resumo, a melhor abordagem é limitar-se a utilizar apenas arquivos STREAM (para entrada ou saída) e arquivos SEQUENTIAL (apenas para entrada de texto) com programas baseados em POSIX. Se você tiver dados binários em arquivo estruturado, escreva um pequeno programa para copiá-lo em um arquivo stream, e então use a versão stream do arquivo com programas POSIX. Se você tiver dados de texto em um arquivo FIXO ou RELATIVO que deseja processar com os programas POSIX, copie primeiro o arquivo em um arquivo STREAM.