Como testar a integridade de arquivo .MEM?

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por clodoaldomonteiro »

Olá amigos,

Tem um erro contumaz que ocorre com meus clientes, que é a quebra do arquivo .MEM, e geralmente ocorre quando há uma queda de energia que de alguma forma grava o arquivo .MEM de forma errada.

Pergunto:
1- Se quando abrimos um arquivo .MEM com o comando REST, este arquivo permanece aberto ou se somente ele ler ar variáveis que estão dentro do arquivo e encerra a conexão com o arquivo .MEM?
2 - Tem como fazer-se um teste de credibilidade de um arquivo .MEM, pois daí poderíamos antecipar uma série de comandos a fim de não passarmos o erro para o cliente final?

Att.
Clodoaldo Monteiro
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por Kapiaba »

Código: Selecionar todos

   A:=4

   NOME:="JOAO"

   SAVE TO ARQVAR// salva todas as variáveis de memória

   // no arquivo ARQVAR.MEM
   RELEASE ALL // apaga todas as variáveis

   RESTORE FROM ARQVAR // restaura as variáveis do arquivo ARQVAR.MEM

   ? A
   ? NOME

http://underpop.free.fr/c/clipper/comandos-clipper.pdf

abs.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Como testar a integridade de arquivo .MEM?

Mensagem por Jairo Maia »

Olá Clodoaldo,
clodoaldomonteiro escreveu:Tem um erro contumaz que ocorre com meus clientes
Estranho é ser costumaz. Já passei por isso, mas muito e muito raramente (3 a 4 vezes acho), e todas as vezes foi após queda de energia, o que significa que coincidiu de ser no momento que o arquivo Mem estava sendo gravado.
clodoaldomonteiro escreveu:1- Se quando abrimos um arquivo .MEM com o comando REST, este arquivo permanece aberto ou se somente ele ler ar variáveis que estão dentro do arquivo e encerra a conexão com o arquivo .MEM?
Apenas lê e fecha o arquivo. Podemos provar isso apagando o arquivo que foi lido em seguida, o que significa que foi fechado (liberado).

Quanto a fazer o teste de integridade, veja se o exemplo abaixo ajuda:

Código: Selecionar todos

Function Main()
 
 Private xMemVar1 := "ABCDE"
 Private xMemVar2 := 10.00
 Private xMemVar3 := Date()
 Private xMemVar4 := .T.
 
 Hb_MVSave( "ArqMem.Mem", "xMemVar*" )  // em Harbour, se extensao omitida sera .HBV
 
 /*
   Quando for restaurar o arquivo Mem, melhor apagar as variaveis que
   se pretende recuperar, garantindo que elas serão as variaveis do arquivo
   em caso de falha, ou seja, nao herdar alguma anterior:
 */
 Release All Like xMemVar*
 
 Hb_MVRestore( "ArqMem.Mem", .T. )  // vamos recarregar as variaveis
 
 //Release xMemvar4  // se descomentar essa linha por exemplo, simula o erro
 
 If Type( "xMemVar1" ) = "U" .Or. ValType( xMemVar1 ) = "U" .Or. ;
    Type( "xMemVar2" ) = "U" .Or. ValType( xMemVar2 ) = "U" .Or. ;
    Type( "xMemVar3" ) = "U" .Or. ValType( xMemVar3 ) = "U" .Or. ;
    Type( "xMemVar4" ) = "U" .Or. ValType( xMemVar4 ) = "U"
  
  Hb_Alert( "Arquivo ArqMem.Mem Corrompido!" )
 
 Else

  Clear Screen
  ? "xMemVar1: ", xMemVar1
  ? "xMemVar2: ", xMemVar2
  ? "xMemVar3: ", xMemVar3
  ? "xMemVar4: ", xMemVar4
  ?
  
 EndIf

Return Nil
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
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á

Como testar a integridade de arquivo .MEM?

Mensagem por Pablo César »

Oi Clodoaldo,

Acho que você poderia ver qual é a mensagem de erro quando ocorre fragmentação no arquivo MEM e atrevo-me a dizer que você poderia tentar corrigir apagando-o quando este der esse erro. Terá que fazê-lo mediante o GETSYS.prg (ao menos no Clipper era o responsável pelos tratamento de erros).
Uma vez deletado, no seu programa, faça a verificação de existência, caso não exista, crie-o novamente com a variaveis default.

Aqui tem um código que poderia te servir para você acessa em baixo nivel:

Código: Selecionar todos

nMemHandle := Fopen( 'Errormem.mem', 2 )
nMemLength := Fseek( nMemHandle, 0, 2)
Fseek(nMemHandle,0)
nCount := 1
Do While Fseek(nMemHandle, 0, 1)+1 < nMemLength
   nMemWidth:= space(18)
   Fread( nMemHandle, @nMemWidth, 18 )
   cVarName := Left( nMemWidth, At( Chr(0) , nMemWidth ) -1 )
   cVartype := Substr( nMemWidth, 12, 1 )
   cVarRec  := Bin2w( Right( nMemWidth, 2 ) )
   nMemCount:= If( cVarType $ Chr(195)+Chr(204), 14+cVarRec, 22 )
   Fseek(nMemHandle, nMemCount, 1)
   cTemp    := Left(cVarName + Space(10), 10)
   cTemp    += ' Tipo ' + Type(cVarName)
   IF "TELA" $ ALLTRIM(cVarName)
      cTemp    += ' < Tela > '
   ELSE
      cTemp    += ' ' + If( Type(cVarName) == 'C', ['] + &cVarName + ['], StrValue( &cVarName ))
   ENDIF
   nBytes   := 0
   Do Case
      Case Type(cVarName) == 'C'
           nBytes += ( nLenTemp := Len( &cVarName. ) )
      Case Type(cVarName) == 'N'
           nBytes += ( nLenTemp := 9 )
      Case Type(cVarName) == 'L'
           nBytes += ( nLenTemp := 2 )
      Case Type(cVarName) == 'D'
           nBytes += ( nLenTemp := 9 )
   EndCase
   Fwrite(     nFhandle, Transform(nLenTemp, '9999999') + ' Bytes -> ')
   FWriteLine( nFhandle, cTemp )
EndDo
Fclose( nMemHandle )
Ferase( 'Errormem.mem' )
Fclose( nFhandle )
No Harbour, tem o código fonte em: https://github.com/harbour/core/blob/ma ... /memvars.c
Eu estou deixando de usar esse tipo de arquivo. Em lugar disso eu utilizo o arquivo INI.
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.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por rochinha »

Amiguinhos,

Clodoaldo?

Voce se lembra deste tópico
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por clodoaldomonteiro »

rochinha escreveu:Amiguinhos,

Clodoaldo?

Voce se lembra deste tópico
Rochinha, agora lembrei do tópico antigo, vou estudar melhor sua solução, mas ela parece que para tratamento de array e no meu caso são variáveis mesmo.
Pablo César escreveu:Oi Clodoaldo,

Acho que você poderia ver qual é a mensagem de erro quando ocorre fragmentação no arquivo MEM e atrevo-me a dizer que você poderia tentar corrigir apagando-o quando este der esse erro. Terá que fazê-lo mediante o GETSYS.prg (ao menos no Clipper era o responsável pelos tratamento de erros).
Uma vez deletado, no seu programa, faça a verificação de existência, caso não exista, crie-o novamente com a variaveis default.


Pablo,
Eu acho que os tratamentos de erros ficam em ERRORSYS ou coisa assim.
Se eu usar o Fopen() para abrir o arquivo, com certeza não terá erro de abertura, pois o arquivo existe, só que está corrompido segundo os padrões .MEM.

Queria saber mesmo é se tem alguma função que verifique sem um arquivo .MEM está hápto a ser aberto pelo comando RESTORE, o fOpen(), por exemplo, retorna um erro e assim posso tratá-lo.
Jairo Maia escreveu:Olá Clodoaldo,

Estranho é ser costumaz. Já passei por isso, mas muito e muito raramente (3 a 4 vezes acho), e todas as vezes foi após queda de energia, o que significa que coincidiu de ser no momento que o arquivo Mem estava sendo gravado.
Jairo, digo que é contumaz, porque tenho uns 50 clientes no interior do Piauí e realmente tem muito problema de queda de energia, mas o que eu queria mesmo era,, por exemplo, testar quantas variáveis tem dentro do arquivo, isso antes de abrir ele com o comando RESTORE.
Kapiaba escreveu:

Código: Selecionar todos

   A:=4

   NOME:="JOAO"

   SAVE TO ARQVAR// salva todas as variáveis de memória

   // no arquivo ARQVAR.MEM
   RELEASE ALL // apaga todas as variáveis

   RESTORE FROM ARQVAR // restaura as variáveis do arquivo ARQVAR.MEM

   ? A
   ? NOME

http://underpop.free.fr/c/clipper/comandos-clipper.pdf

abs.
Kapiaba, eu já sei abrir o arquivo e o que quero mesmo é testá-lo antes de abrir.

Fico grato pela atenção de todos.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por clodoaldomonteiro »

Pessoal, o erro que acontece é esse:
Imagem
Abraços.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por rochinha »

Amiguinho,

Verifique se nas variaveis que você está guardando se algum caracter indevido esteja sendo armazenado.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Como testar a integridade de arquivo .MEM?

Mensagem por Jairo Maia »

Olá Clodoaldo,

Agora que vi que você usa xHarbour. O exemplo que passei funciona apenas no Harbour, e a função Hb_MvRestore() não causa esse erro mesmo que você teste abrindo um arquivo qualquer, apenas não carrega as variáveis. Por isso é possível testar da forma que passei. No entanto, como o xHarbour passou por várias atualizações, será que estas funções não foram compatibilizadas?
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por clodoaldomonteiro »

Olá,
rochinha escreveu:Amiguinho,

Verifique se nas variaveis que você está guardando se algum caracter indevido esteja sendo armazenado.
Rochinha,
Vi em um arquivo .MEM "quebrado" que é como se os caracteres separadores dos campos não estivessem completos ou algum nome de variável faltando.
Jairo Maia escreveu:Olá Clodoaldo,

Agora que vi que você usa xHarbour. O exemplo que passei funciona apenas no Harbour, e a função Hb_MvRestore() não causa esse erro mesmo que você teste abrindo um arquivo qualquer, apenas não carrega as variáveis. Por isso é possível testar da forma que passei. No entanto, como o xHarbour passou por várias atualizações, será que estas funções não foram compatibilizadas?
Jairo,
É, uso o xHarbour 1.0, pois não consegui converter minha aplicação para o Harbour 3.0. É que estou usando a GTWVW, onde uso menus Windows com telas Console.
Vou verificar se existe a função que você indicou.

Obrigado a todos.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por clodoaldomonteiro »

Tentei chamar o Comando RESTORE dentro de um Try:

Código: Selecionar todos

      Try
         REST FROM ( arqconf ) ADDI                                // restaura configuracoes gravadas
      Catch
         FErase( arqconf )
         ? 'Falha na abertura do arquivo de Configura‡äes.'
         Wait 'Tente entrar no sistema novamente.'
         Quit
      End
Mas não deu certo também.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
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á

Como testar a integridade de arquivo .MEM?

Mensagem por Pablo César »

Então Clodoaldo, depois de você ter tentado abrir e não conseguiu, porque o MEM está corrompido, após o teu TRY basta verificar se tais varíáveis tem valor Nil e aí entaõ você as grava no MEM novamente.
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.
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Como testar a integridade de arquivo .MEM?

Mensagem por clodoaldomonteiro »

Pablo...

Fiz um teste para ver a execução do Try, como está abaixo :

Código: Selecionar todos

Try
   Wait 1
   RESTORE FROM ( arqconf ) ADDI                // restaura configuracoes gravadas
   Wait 2
Catch
   FErase( arqconf )
   ? 'Falha na abertura do arquivo de Configura‡äes.'
   Wait 'Tente entrar no sistema novamente.'
   Quit
End
e vi que o sistema mostra o primeiro WAIT, e logo depois tenta fazer o RESTORE e mostrado a mensagem de erro que postei aqui, sendo assim, não temo eu tratar o erro, não é como uma função, que retorna alguma coisa para podermos ver o resultado.

Grato pela atenção.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
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á

Como testar a integridade de arquivo .MEM?

Mensagem por Pablo César »

clodoaldomonteiro escreveu:não temo eu tratar o erro, não é como uma função, que retorna alguma coisa para podermos ver o resultado.
Você não entendeu o que eu quis dizer.
Pablo César escreveu:após o teu TRY basta verificar se tais varíáveis tem valor Nil e aí entaõ você as grava no MEM novamente.
Eu me equivoquei quando eu disse: "se tais varíáveis tem valor Nil" na verdade você verifica se existem com ValType.

Veja este exemplo:

Código: Selecionar todos

Function Main()
Local arqconf:="Clientes.mem", lErro:=.F.
Local CLI_NOME, CLI_NASCEU, CLI_SEXO

If !File(arqconf)
   CLI_NOME:="Clodoaldo"
   CLI_NASCEU:=DATE()-(365*30)
   CLI_SEXO:="MASCULINO"
   SAVE TO CLIENTES ALL LIKE CLI_*
   RELEASE ALL LIKE CLI_*
Endif

nMemHandle := Fopen( arqconf, 2 )
Fseek(nMemHandle,0)
Fwrite(nMemHandle,Chr(1)+Chr(2)+"Queda de Luz")
Fclose( nMemHandle )

BEGIN SEQUENCE
   Restore from ( arqconf ) Additive
RECOVER USING oError
   FErase( arqconf )
   ? 'Falha na abertura do arquivo de Configurações. ('+(oError:Description)+")"
   Inkey(0)
   // Quit
END

If ValType(CLI_NOME) = "U"
   CLI_NOME:="Clodoaldo"
   lErro:=.T.
Endif
If ValType(CLI_NASCEU) = "U"
   CLI_NASCEU:=DATE()-(365*30)
   lErro:=.T.
Endif
If ValType(CLI_SEXO) = "U"
   CLI_SEXO:="MASCULINO"
   lErro:=.T.
Endif
If lErro .or. !File(arqconf)
   SAVE TO CLIENTES ALL LIKE CLI_*
Endif
? CLI_NOME
? DToC(CLI_NASCEU)
? CLI_SEXO
Return Nil
Substitua o BEGIN SEQUENCE por Try e RECOVER USING oError por Catch para que funcione em xHarbour.

Na minha opinião, você tendo os nomes e o valor default de cada variável, fica fácil você ver se carregou ou não.

Só que eu não consegui reproduzir o mesmo erro. Podia er sido muito bom você ter anexado o arquivo corrupto.

Aqui tem um tópico que fala de "Restore failed, unsupported type: 65408 for":
https://pctoledo.org/forum/viewto ... 853#p50853

Na minha opinião, você não precisava dar um QUIT quando ocorre o erro. Você teria duas opções válidas: mostrar o erro ou simplesmente omiti-lo. Ao omitir o erro você deleta o arquivo e cria novamente. Funções de baixo nível poderia ajudar a recuperar al, mas acho que não valeria a pena.
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.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Como testar a integridade de arquivo .MEM?

Mensagem por Jairo Maia »

Olá Pablo,

Permita-me apenas para registro o seguinte:

Para saber se uma variavel existe, a função é:

Código: Selecionar todos

Type( "VariavelEntreAspas" )  // verifica se determinada variável existe
Precisa ser entre aspas, ou seja, passada a função Type() como string, afinal a idéia é saber se existe alguma variável com esse nome.

Para saber o tipo do conteúdo de uma variável, a função é:

Código: Selecionar todos

ValType( VariavelSemAspas )  // verifica o tipo do conteúdo da variavel
Não pode ter aspas, e a variável necessariamente precisa existir, ou se tem o RTE: Variável não existe. Neste caso não haverá erro se colocar entre aspas, porém, sempre retornará type = "C", pois o conteúdo é string.

Penso então que em casos onde esse tipo de verificação seja necessário, podemos concatenar ambas dessa forma, e claro, nesta ordem:

Código: Selecionar todos

If Type( "xVariavel" ) = "U" .Or. ValType( xVariavel ) = "U"
 alert( "variável inexistente ou com conteúdo Nulo" )
EndIf
Ou se preferir identicar exatamente a situação de determinada variável, podemos fazer assim:

Código: Selecionar todos

If Type( "xVariavel" ) = "U"
 alert( "variável inexistente" )
ElseIf ValType( xVariavel ) = "U"
 alert( "variável com conteúdo Nulo" )
EndIf
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Responder