Ler e regravar um arquivo TXT com as funções de baixo nível

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Avatar do usuário
billy1943
Usuário Nível 4
Usuário Nível 4
Mensagens: 570
Registrado em: 12 Mai 2009 17:33
Localização: Bauru-SP

Ler e regravar um arquivo TXT com as funções de baixo nível

Mensagem por billy1943 »

Procurei de todas as formas de uso das funções FOPEN, FSEEK, FREAD, FWRITE e FCLOSE, , no NG do Clipper, para fazer o seguinte:

1. Tenho um arquivo texto (relatório gerado em .TXT) e preciso agora usá-lo no NODOSIMP que não admite caracteres de controle;

2. Pretendo gerar outro arquivo ou ainda regravar o mesmo arquivo original excluindo caracteres de controle que estão no final do arquivo (em hexadecimal OC, 0D, 20, 12, 1B, 40, 1B) e incluindo também em hexadecimal ( OD, 0A )

3. Vamos supor que o arquivo fonte tem 5.174 caracteres e pretendo excluir os últimos 7 caracteres do final do arquivo, já usei a FSEEK para obter o tamanho total, mas estou parado agora sobre como usar a FWRITE para gravar os 5.167 bytes anteriores. Depois disso, gravarei os caracteres em substituição.

Uma vez vi neste fórum uma solução apontada para retirar caracteres de controle invisíveis que estavam sobrando no final do arquivo, mas não encontrei mais esse tópico.
Esses caracteres invisíveis são gravados automaticamente por alguns editores de texto do DOS.
O bom do computador é que ele resolve os problemas, sem nunca levantar nenhum.
Hoje atuo mais com Clipper 52E, e um pouquinho com XHarbour.
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Ler e regravar um arquivo TXT com as funções de baixo nível

Mensagem por Pablo César »

Olá Billy,

Você precisa isso pra Clipper o Harbour ?
Uma ideia que talvez não venha ao caso mas ajude. Por quê ao invés de remover comando de impressão, você não cria sem ? Isto é, você poderia criar praticamente de forma simultânea dois arquivos: um de visualização (digamos) e o outro de impressão, talvez com extensão diferente.

Um solução bem simples eu utilizei o CharRem da Ca-Tools. Uma vez criado o arquivo, leia na memória, dependendo o tamanho (se for pra Clipper) com MemoRead e utilizas essa função para remover os caracteres de comandos e depois re-gravá-los.

Existem muitos tópicos de funções de baixo nível. Estas funções são mutos rápidas e eficientes. Só não entendi qual é a sua dúvida.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Ler e regravar um arquivo TXT com as funções de baixo nível

Mensagem por alxsts »

Olá!

Como o tópico está na seção Clipper, suponho que esta seja a linguagem usada. Como disse o colega, o ideal seria gerar o arquivo sem esses caracteres mas, na impossibilidade de fazer isto, segue o código abaixo, que faz o que você precisa (retira os últimos 7 bytes do arquivo).

É preciso verificar se esse arquivo fonte é mesmo um texto em ASCII e para que servem os caracteres que você mencionou:
billy1943 escreveu: caracteres de controle que estão no final do arquivo (em hexadecimal OC, 0D, 20, 12, 1B, 40, 1B)
É preciso verificar também se os registros são de tamanho fixo ou variável, como as linhas estão separadas (qual é o separador) se é que estão separadas, etc...

Código: Selecionar todos

#include "fileio.ch"

FUNCTION Main()

   SetMode( 25,80)
   CLS

   IF FConvert( "Teste.Txt", "Teste.New" )
      Alert( "Arquivo convertido!", , "W+/B" )
   ELSE
      Alert( "Falha ao converter o arquivo!" )
   ENDIF

RETURN NIL
//------------------------------------------------------------------------------

STATIC FUNCTION FConvert( cInFile, cOutFile )

   LOCAL lRet := .F.
   LOCAL nInFileHandle := 0
   LOCAL nOutFileHandle := 0
   LOCAL nTotalBytes
   LOCAL nBytesToWrite
   LOCAL nBytesRead
   LOCAL cBuffer

   BEGIN SEQUENCE

      IF Empty( cInFile )  .OR. ;
         Empty( cOutFile ) .OR. ;
         ( !File( cInFile ) )
         BREAK
      ENDIF

      // abre o arquivo a ser convertido
      IF ( nInFileHandle := FOPEN( cInFile, FO_READ + FO_EXCLUSIVE ) ) == -1
         BREAK
      ENDIF

      // Posiciona o ponteiro no final do arquivo e obtem o tamanho do mesmo, em bytes
      nTotalBytes := FSEEK(nInFileHandle, 0, FS_END)
      //
      // Move o ponteiro de volta para o início do arquivo
      FSEEK(nInFileHandle, 0)

      // Considerando que os 7 últimos butes serão ignorados, define o tamanho do
      // arquivo de saida em bytes
      nBytesToWrite := (nTotalBytes - 7 )

      // cria o arquivo de saída
      IF ( nOutFileHandle := FCREATE(cOutFile, FC_NORMAL))  == -1
         BREAK
      ENDIF

      // inicializa o buffer de leitura com a quantidade de espaços que se pretende ler
      cBuffer := SPACE( nBytesToWrite )

      // executa a leitura preenchendo o buffer (note que a variável cBuffer é
      // passada por referência (prefixado por @)
      nBytesRead := FREAD( nInFileHandle, @cBuffer, nBytesToWrite )

      // grava o arquivo de saída
      IF FWRITE(nOutFileHandle, cBuffer, nBytesToWrite ) == nBytesToWrite
         cBuffer := Chr(13) + Chr(10)
         // grava o separador da última linha (CR + LF ou 0D + 0A em Hexadecimal)
         IF FWRITE(nOutFileHandle, cBuffer, 2 ) == 2
            lRet := .T.
         ENDIF
      ENDIF

   END SEQUENCE

   // fechamento dos arquivos
   IF nInFileHandle  != 0  ;   FCLOSE( nInFileHandle )    ;   ENDIF
   IF nOutFileHandle != 0  ;   FCLOSE( nOutFileHandle )   ;   ENDIF

   RETURN lRet
//------------------------------------------------------------------------------
Este código demonstra a utilização das funções de baixo nível. Espero que ajude.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
billy1943
Usuário Nível 4
Usuário Nível 4
Mensagens: 570
Registrado em: 12 Mai 2009 17:33
Localização: Bauru-SP

Ler e regravar um arquivo TXT com as funções de baixo nível

Mensagem por billy1943 »

Ficou perfeito !

Apesar de não informar que preciso da rotina para sistema em Clipper, o nosso amigo Alexandre esgotou o assunto das funções de baixo nível do Clipper e está rodando exatamente como o desejado.

Eu me assustei quando vi que somente havia sido reduzido o tamanho do arquivo de saída em 5 (cinco) btyes, mas depois verifiquei que já tinham sido incluídos os caracteres hexa 0D OA ou seja o CR + LF separador da última linha gravada.

O Pablo César aventou uma possibilidade que eu já estava "maquinando" pois hoje dependendo da saída a ser dada ao relatório eu
preparo o arquivo de formas diferentes, pois posso:

1. Exibir na tela usando a função FILEREAD
2. Gravar em arquivo SPOOL com vistas à impressão futura
3. Gravar para uso pelo NODOSIMP - USB
4. Gravar para uso do WORD - USB
5. Impressão para impressora escrava de impacto (LPT1)

Mas somente gero para um único modelo e se escolher outra forma de saída tenho que produzir novamente a posição já com vistas à
saída pretendida.

Quanto aos caracteres que estão no final do arquivo informo que são controles para o tamanho dos caracteres, desabilitando
gráficos, etc., aqueles caracteres de controle do tempo das impressoras de impacto, pois tem clientes que ainda as usam...
Quando a impressão é derivada para impressoras em USB, pelo NODOSIMP ou WORD, eles podem ser dispensados.
O bom do computador é que ele resolve os problemas, sem nunca levantar nenhum.
Hoje atuo mais com Clipper 52E, e um pouquinho com XHarbour.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Ler e regravar um arquivo TXT com as funções de baixo nível

Mensagem por alxsts »

Olá!

só uma observação: em Clipper, se os teus arquivos de entrada tiverem mais que 65535 bytes (64Kb) você precisará ler o arquivo em partes de até 64Kb e ir gravando essas partes no arquivo de saída (DO ... WHILE), eliminando os bytes finais da última parte.
[]´s
Alexandre Santos (AlxSts)
Responder