Rotina com bloqueio de arquivo

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Vandi
Usuário Nível 2
Usuário Nível 2
Mensagens: 83
Registrado em: 16 Set 2011 23:26
Localização: Brasilia-DF

Rotina com bloqueio de arquivo

Mensagem por Vandi »

Boa noite,

Por gentileza, já fiz alguns testes utilizando flock() para bloqueio de arquivo, mas não obtive o êxito esperado, por isso recorro a ajuda aqui do grupo.
Preciso de uma rotina exemplo de acesso a arquivo que satisfaça as seguintes condições:
1)-Se o mesmo não estiver bloqueado, bloqueia-o e segue a rotina, com o desbloqueio no final da rotina;
2)-Se o mesmo estiver bloqueado, emite uma mensagem e volta ao início.

Aguardo retorno,

Agradecimentos antecipados,

Gilvandi
Imatech
Usuário Nível 3
Usuário Nível 3
Mensagens: 350
Registrado em: 24 Ago 2010 23:48
Localização: Goiânia-GO

Rotina com bloqueio de arquivo

Mensagem por Imatech »

Assunto já discutido no tópico:

https://pctoledo.org/forum/viewto ... ock#p76113



Aproveito para sugerir o estudo da pasta contrib\xhb que contem bons exemplos para uso imediato...
\harbour\contrib\xhb\ttable.prg

Código: Selecionar todos


NetDbUse( cDataBase, cAlias, nSeconds, cDriver, lNew, lOpenMode, lReadOnly )
NetLock( nType, lReleaseLocks, nSeconds )
NetFunc( bBlock, nSeconds )
NetOpenFiles( aFiles )
NetDelete()
NetReCall()
NetRecLock( nSeconds )
NetFileLock( nSeconds )
NetAppend( nSeconds, lReleaseLocks )
NetCommitAll()
IsLocked( nRecId )
NetError()
SetNetDelay( nSecs )
SetNetMsgColor( cColor )
TableNew( cDBF, cALIAS, cOrderBag, cDRIVER, lNET, cPATH, lNEW, lREADONLY )
GetTable( cAlias )
etc...

M., Ronaldo

by: IMATECH

IMATION TECNOLOGIA
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Rotina com bloqueio de arquivo

Mensagem por alxsts »

Olá!

Pelos detalhes fornecidos, é mais prático abrir o arquivo de modo exclusivo.

Código: Selecionar todos

USE <xcFile> EXCLUSIVE NEW
. Ao final do processamento fechar o arquivo.
[]´s
Alexandre Santos (AlxSts)
Vandi
Usuário Nível 2
Usuário Nível 2
Mensagens: 83
Registrado em: 16 Set 2011 23:26
Localização: Brasilia-DF

Rotina com bloqueio de arquivo

Mensagem por Vandi »

Alexandre,
Bom dia...

Ok, mas eu te pergunto: digamos que eu abra o arquivo em modo exclusive, se outra estação for abrir o mesmo arquivo não dará um erro?

Gilvandi
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Rotina com bloqueio de arquivo

Mensagem por alxsts »

Olá!

Sim, a outra estação não conseguirá acessar o arquivo até que você o feche. O mesmo acontece com o arquivo se você colocar um FLock() nele.

Nos dois casos, o intuito é exatamente evitar que outros usuários acessem o arquivo. Não é isso que você precisa?
[]´s
Alexandre Santos (AlxSts)
Vandi
Usuário Nível 2
Usuário Nível 2
Mensagens: 83
Registrado em: 16 Set 2011 23:26
Localização: Brasilia-DF

Rotina com bloqueio de arquivo

Mensagem por Vandi »

Alexandre,
Boa tarde...

Sim, é isso mesmo que preciso, porém queria que, na tentativa de acesso ao arquivo por outra estação o sistema emita um aviso dizendo que o mesmo está inacessível e saísse da rotina, entendeu?
Como você aconselhou, já coloquei a abertura do arquivo em modo EXCLUSIVE, fiz alguns testes e funcionou OK. Mas não quero que a outra estação saia do programa em virtude de um erro por não conseguir acessar o arquivo, gostaria que o sistema fizesse uma crítica apenas.

Gilvandi
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina com bloqueio de arquivo

Mensagem por Toledo »

Gilvandi, o Ronaldo passou várias funções para estudo, uma delas acho que iria fazer o que você precisa (NetDbUse), mas vou passar um função que muita gente aqui no fórum deve utilizar:

Código: Selecionar todos

FUNCTION Abre_Dbf(xcArquivo,xcAlias,lModo,nTentativa)
LOCAL lSempre
lSempre := (nTentativa == 0)
IF EMPTY(SELECT(xcAlias))
 DO WHILE (lSempre .OR. nTentativa > 0) .AND. INKEY() <> 27
   IF lModo                     && .T. ABRE ARQUIVO EXCLUSIVO ...
      USE (xBase+xcArquivo) ALIAS (xcAlias) EXCLUSIVE NEW
   ELSE                         && .F. ABRE ARQUIVO COMPARTILHADO ...
      USE (xBase+xcArquivo) ALIAS (xcAlias) SHARED NEW
   END
   IF (.NOT. NETERR())          && COM SUCESSO ...
      RETURN (.T.)
   END
   INKEY(1) 	          	&& TENTATIVAS 1 SEGUNDO ...
   nTentativa := nTentativa - 1
 END
ELSE
 SELE SELECT(xcAlias)
 RETURN (.T.)
ENDIF
RETURN (.F.)
Modo de usar:

Código: Selecionar todos

IF !Abre_Dbf("Arquivo","Alias",.T.,10)
  MsgInfo("Não foi possível abrir o Arquivo")
  RETURN
ENDIF
Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Vandi
Usuário Nível 2
Usuário Nível 2
Mensagens: 83
Registrado em: 16 Set 2011 23:26
Localização: Brasilia-DF

Rotina com bloqueio de arquivo

Mensagem por Vandi »

Toledo,
Boa tarde...

Obrigado pela atenção... vou pegar essa rotina que vc dispôs aí e fazer uns testes mais tarde...

Gilvandi
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Rotina com bloqueio de arquivo

Mensagem por Poka »

Olá a todos

Toledo, sempre usei uma rotina parecida com essa sua.
Esses dias fazendo um teste + detalhado, percebi o seguinte:

Se tentar abrir um arquivo como exclusivo e o esse mesmo arquivo já foi aberto em outro terminal como exclusivo, o sistema da erro na abertura e trava o sistema antes do neterr

pergunto: para que serve o neterr?

Código: Selecionar todos

func abre_dbf(xNomearq,xModo,xAlias)
   // verifica se houve erro na abertura do arquivo
   local val:=.t.
   if ! xmodo   // tenta abrir conmpartilhado
      IF empty(select(xAlias))
         use (xnomearq) alias (xalias) shared new
      endif
   else 
			   // exclusivo
      IF empty(select(xAlias))
         use (xnomearq) alias (xalias) exclusive new
      endif
   endif
   if neterr()
      val=.f.  // nao abriu
   endif

retu (val)
[code]
Poka
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á

Rotina com bloqueio de arquivo

Mensagem por Pablo César »

pergunto: para que serve o neterr?
Ele serve para retornar o erro justamente de compartilhamento do arquivo. Ai o programa não será abortado no caso que você trate esse erro.
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
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Rotina com bloqueio de arquivo

Mensagem por Poka »

Pablo,

obrigado por responder.

Eu já uso o neterr, acontece que o erro dá na linha
USE (XNOMEARQ)
não chega até a linha do neterr.
Sempre achei que o neterr "trabalhasse" igual as funcões FOPEN() e FERROR(), onde
o erro não trava no fopen() e voce testa na função ferror(), a não ser que na minha rotina esteja faltando algo.

Poka
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á

Rotina com bloqueio de arquivo

Mensagem por Pablo César »

Eu não sei como você está usando ao ponto de dizer que não esteja funcionando. Olha eu fiz estes testes de exemplos baseado um no código do Toledo e o outro do Maligno. Aqui está funcionando perfeitamente.
Sempre achei que o neterr "trabalhasse" igual as funcões FOPEN() e FERROR()
Não funcionam exatamente iguais*, mas dá para obter o mesmo resultado.

Faça os testes indicados nesse tópico com os executáveis em anexo, para comparar casa a caso (aconselho que sejam feito na linha de comando).

*Digo não iguais, porque o FOpen tem mais opções que o USE. O FOpen pode abrir os arquivos em modo:
&nbspModo&nbsp&nbspValor&nbsp
&nbspREAD&nbsp&nbsp0&nbsp
&nbspWRITE&nbsp&nbsp1&nbsp
&nbspREADWRITE&nbsp&nbsp2&nbsp
&nbspEXCLUSIVE&nbsp&nbsp16&nbsp
&nbspDENYWRITE&nbsp&nbsp32&nbsp
&nbspDENYREAD&nbsp&nbsp48&nbsp
&nbspDENYNONE&nbsp&nbsp64&nbsp
Apesar de que o USE pode abrir também em READONLY, isto é impedido quando é aberto em modo EXCLUSIVE. Já isto pode ou não acontecer com FOpen(), tudo depende com qual modo você irá abrir o arquivo (ver tabela acima). Faça outro comparativo abrindo em ReadOnly com estes exemplos aqui em anexo.
Anexos
TESTES.rar
(168.73 KiB) Baixado 310 vezes
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
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Rotina com bloqueio de arquivo

Mensagem por Poka »

Pablo,

Mais uma vez obrigado pela sua paciência e dedicação.

1) testei a sua rotina

Resultado:

perfeito, era isso mesmo que eu imaginava que fizesse, mas no meu sistema dava erro. No meu sistema trabalho normal abrindo os arquivos, mas num caso de precisar abrir exclusivo dava erro. Por isso a minha pergunta "para que servia o neterr?".

2) No meu sistema desativei a minha rotina, coloquei a sua.

Resultado:

O erro continua
FALHA DBFCDX\1001 ERRO DE ABERTURA: ARQUIVO.DBF
na linha do USE NOMEARQ antes do neterr.

3) Criei novo projeto com as mesmas configurações iniciais que utilizo (achei que pudesse ser alguma configuração que estivesse causando o erro), utilizo Harbour + Minigui.

Resultado:

perfeito, sem nenhum erro.


Vou continuar "quebrando a cabeça" por aqui para ver se descubro qual o problema, (pelo menos agora sei que o neterr funciona como o esperado) "

Assim que solucionar o problema volto nesse tópico para postar o resultado.

Um abraço


Poka
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á

Rotina com bloqueio de arquivo

Mensagem por Pablo César »

Poka escreveu:num caso de precisar abrir exclusivo dava erro. Por isso a minha pergunta "para que servia o neterr?"
O NetErr() irá dar retorno de erro, quando este for tentar abrir em modo EXCLUSIVO, pois se tiver alguma estação aberto antes, seja em modo COMPARTILHADO ou EXCLUSIVO, irá dar erro igual.

A abertura em modo EXCLUSIVO tem que ser evitado o máximo possível em uma rede. Tudo tem que ser avaliado, buscar outra solução pode ser o caso.
O erro continua
FALHA DBFCDX\1001 ERRO DE ABERTURA: ARQUIVO.DBF
na linha do USE NOMEARQ antes do neterr.
Se nessa linha só contiver USE NOMEARQ sem mais nada. Então é o mesmo que abrir em modo EXCLUSIVO e se outra estação estiver com o arquivo aberto, evidentemente irá dar erro. Aconselho também abrir o DBF antes e depois os índices após ter passado pelo NetErr().
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
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Rotina com bloqueio de arquivo

Mensagem por Poka »

Pablo

Resolvido!!
PUBL OERRANTES, OERR
// LMYERROR = .T. - SI OCURRIO REALMENTE UN ERROR, .F. - PARA CONTROLAR LOS BREAK
PUBL LMYERROR := .F.
ERRORBLOCK({ |OBJERR| MYERRORFUNC(OBJERR) })
Esse texto estava na rotina inicial, que serve para todos os sistemas. Foi só desativar que funcionou corretamente.

Quando comecei a utilizar o x(harbour), devo ter copiado de alguma rotina exemplo, por isso o neterr não estva funcionando como devia.

Obrigado Pablo

Poka
Responder