Página 1 de 2
Como testar a integridade de arquivo .MEM?
Enviado: 23 Jan 2015 11:07
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
Como testar a integridade de arquivo .MEM?
Enviado: 23 Jan 2015 11:15
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.
Como testar a integridade de arquivo .MEM?
Enviado: 23 Jan 2015 12:34
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
Como testar a integridade de arquivo .MEM?
Enviado: 23 Jan 2015 13:35
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.
Como testar a integridade de arquivo .MEM?
Enviado: 24 Jan 2015 04:24
por rochinha
Amiguinhos,
Clodoaldo?
Voce se lembra
deste tópico
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 12:31
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, eu já sei abrir o arquivo e o que quero mesmo é testá-lo antes de abrir.
Fico grato pela atenção de todos.
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 12:46
por clodoaldomonteiro
Pessoal, o erro que acontece é esse:

Abraços.
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 13:44
por rochinha
Amiguinho,
Verifique se nas variaveis que você está guardando se algum caracter indevido esteja sendo armazenado.
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 13:49
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?
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 17:57
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.
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 18:04
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.
Como testar a integridade de arquivo .MEM?
Enviado: 31 Jan 2015 18:32
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.
Como testar a integridade de arquivo .MEM?
Enviado: 02 Fev 2015 14:45
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.
Como testar a integridade de arquivo .MEM?
Enviado: 02 Fev 2015 19:24
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.
Como testar a integridade de arquivo .MEM?
Enviado: 05 Fev 2015 13:29
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