Cadastre seu e-mail para receber as novidades desse blog. Você pode cancelar a qualquer momento.

Delivered by FeedBurner

Assista ao vídeo descritivo acima; depois clique na imagem abaixo para adquirir o seu GUIA PRÁTICO PARA PASSAR EM CONCURSO PÚBLICO EM UM ANO.

Google Website Translator

Postagem em destaque

Automação Residencial com arduíno

Já pensou em criar sua própria casa inteligente, com automações em todos os cômodos? Sem gastar muito? Sem ser um engenheiro ou algo parecid...

Pesquise nesse Blog e na WEB com o Google

sexta-feira, 23 de dezembro de 2011

Microcontroladores

Os microcontroladores têm uma grande quantidade de utilidades. São pequenos processadores que utilizam o conceito de máquina de estados para controlar objetos. Por exemplo, podemos fazer um pequeno controlador para dois semáforos. Veja os esquemas:


Um microcontrolador simples para dois semáforos.

Esquema da máquina de estados.


Há dois sinais de entrada: clk (clock) e rst (reset). O clock é o sinal que faz com que o microcontrolador mude de estado, e deve ser gerado por outro circuito externo gerador de clock. O reset é o um sinal que faz o circuito voltar para o estado inicial e é utilizado quando o circuito é ligado (iniciado).
A caixa amarela no esquema contém a máquina de estados que envia os sinais corretos para a saída do controlador. Esses sinais devem ser interpretados por outro circuito que liga as luzes corretas nos dois semáforos.





Há ainda três portas lógicas do tipo "OU" que completam a lógica do circuito.
As saídas do microcontrolador são: count (contador), que informa em qual estado está o circuito, semaforo1 e semaforo2 que ligam as luzes corretas nos dois semáforos. Os esquemas acima foram criados no programa Quartus II. Abaixo está o resultado de uma simulação do circuito feita no mesmo programa:


Simulação. Observe que o sinal clk (clock) controla o circuito e o ativamento das luzes.

IRQs

1 – Para que servem

A arquitetura dos PCs é estruturada de tal modo a permitir extrema flexibilidade de expansão e também grande capacidade de adaptação. Dentre os recursos que garantem estas facilidades estão os eventos de IRQ (Interrupt Request-Requisição de interrupção) e os processos de DMA (Direct Memory Access-Acesso direto á memória), aliados também aos espaços de memória conhecidos como regiões de I/O. Fica a cargo da equipe de programação de drivers adaptar o software e os dispositivos para um padrão básico.
Muito do que está por trás desta flexibilidade é para a manutenção da compatibilidade com as gerações anteriores de PCs. Os mecanismos de geração e utilização de IRQ e DMA continuam muito similares aos dos PCs XT. O novo barramento PCI e obviamente seu derivado AGP são os que introduziram algumas novidades. A estrutura básica do hardware manteve-se quase inalterada durante as mudanças de gerações, havendo muito mais progressos relativos ao software e à abordagem do tratamento e interpretação das sinalizações. Este último aspecto é bastante sensível no que diz respeito aos drivers. O hardware fica, mas os drivers precisam ser atualizados ou reescritos.





2 – Conceito.

IRQ é um evento que pode ocorrer em qualquer instante por conta de diversos tipos de atividades, servindo então, para anunciar que algo esperado ou inesperado ocorreu.
Uma IRQ é utilizada por dispositivos anexados ao PC quando é necessária a atenção do sistema. Geralmente as IRQs são endereçadas aos drivers de dispositivos ou ao Bios. Essas duas entidades são capazes de reconhecer o que o subsistema requer ou está anunciando.
Se não fosse pelo mecanismo de geração de controle de IRQs, os PCs estariam condenados a pouca flexibilidade dos sistemas de monitoração periódica, ou em inglês, técnicas de polling, (pesquisa). No modo de polling, com certa regularidade, o PC deve questionar a toda possível porta de conexão, se o subsistema precisa de alguma coisa ou tem algo a oferecer. Fica claro que este mecanismo é um devorador de tempo, só sendo viável se um subsistema dedicado fosse o responsável e não a própria CPU, mas nesse caso o custo de implementação seria mais elevado do que o de IRQs.
Pelo menos um subsistema do PC ainda funciona pelo método de polling. Trata-se do joystick, já que as rotinas de leitura devem ser implementadas pelo próprio programa consumindo assim recursos preciosos da CPU.
Geralmente toda placa auxiliar requer a alocação de uma IRQ. Um caso bastante conhecido de subsistema que não requer este sinal são as placas aceleradoras 3D que utilizam o chipset Voodoo e Voodoo2 da 3dfx. Toda a comunicação com o sistema é feita por meio do sistema de vídeo principal, através dos elaborados drivers da placa.


3 – Exemplo prático.

Uma central de alarme informatizada. Pode-se construir uma matriz de sensores e conecta-la a um circuito lógico que armazene a condição de cada sensor. Não é difícil que este circuito perceba que algum dos sensores mudou de estado. Assim que este evento ocorre, uma IRQ pode ser acionada e assim o programa de monitoração pode tomar alguma atitude, como alterar o estado de um desenho na tela indicando qual sensor disparou o evento. O circuito lógico de controle pode armazenar o estado de todos os sensores num buffer local, que após a transferência para a memória acessível pela CPU pode indicar como alterar o desenho na tela.

4 – Sinais de IRQ

Uma IRQ é naturalmente um evento gerado por hardware. Na verdade há também IRQs geradas por software, geradas para auxiliar a execução de um programa ou simular uma ocorrência no hardware.
As IRQs disponíveis para hardware são em número de 16 nos PCs AT (IRQ0 a IRQ15) e em número de 8 nos PCs XT (IRQ0 a IRQ7). Por software há um total de 239 (256 ao todo – 16 de hardware – 1 de NMI).
Entre as interrupções geradas por software, há uma classe especial não inclusa nas 16 computadas anteriormente, reunidas numa única chamada de NMI (NonMaskable Interrupt). Ela não pode ser ignorada pelo PC com concordância da CPU, ou seja , via programação – o processo chamado de “mascaramento” que serve para impedir que as interrupções sejam atendidas pela CPU. As interrupções que ativam a NMI sempre são fatais, como erro de paridade da memória ou alguma anormalidade em um dos subsistemas da placa-mãe especialmente detectada pelo chipset. O sinal desta interrupção NMI é diretamente ligado à CPU por uma via de mesmo nome, com o objetivo de parar imediatamente a atual tarefa e fazer-se manifestar ao usuário. Sempre que uma NMI é gerada, o sistema só pode sair deste estado sendo resetado ou desligado.
As 16 IRQs disponíveis atualmente são gerenciadas no hardware pelo chipset da placa-mãe, normalmente o Soulth Bridge, também responsável pela oferta de uma controladora IDE/ATA.
No processador há apenas uma via que indica que há serviços de IRQ pendentes (INTR). A identificação da IRQ gerada dá-se por meio de registradores do chipset.
No chipset há vias específicas para levantar uma IRQ. No barramento ISA 16 bits, (o ISA com extensão), há 11 vias nomeadas de IRQ3 a IRQ14, com exceção da IRQ8. Já no barramento PCI há apenas 4 vias.






5 – IRQs por software.

O PC oferece 256 interrupções, das quais no máximo 239 podem ser acessadas via software. As interrupções de software mais conhecidas são aquelas oferecidas pelos serviços do Bios. Um programador também pode criar serviços próprios que atendam um pedido de interrupção gerado por um outro programa. Sob Windows é complicado criar este tipo de serviço normalmente e há outros recursos como múltiplas tarefas e threads que podem quase sempre atender aos mesmos objetivos.

6 – Tratamento de IRQs.

Quando acontece a inicialização da máquina, os dispositivos onboard ativos (não desabilitados pelo usuário), recebem determinadas IRQs escolhidas pelo usuário ou realmente fixas por projeto. As demais IRQs são alocadas quando acontece a inicialização de drivers associados com seus respectivos dispositivos, caracterizando o Plug and Play.
Assim que uma interrupção é requisitada, alguma medida deve ser tomada. É sempre um programa, seja ele um driver, ou um programa no hardware (firmware) que é chamado pelo processador para resolver a interrupção. Na inicialização do PC, cada IRQ aponta para um endereço na memória correspondente a um programa que supostamente sabe interpretar o pedido de interrupção. Absolutamente toda IRQ é associada a uma rotina de tratamento, nem que essa rotina não faça nada além do mínimo requerido, simplesmente para que o sistema não trave caso uma IRQ sem utilidade seja acidentalmente ativada.

7 – Utilização das IRQs.

Na primeira concepção do PC os projetistas acreditavam que cada dispositivo que necessitasse de uma IRQ deveria ter uma exclusiva para si. O resultado foi um barramento ISA com diversas vias elétricas dedicadas exclusivamente á sinalização individual de IRQs. Nem ao menos utilizou-se uma forma de multiplexação para economizar na quantidade de vias. Por exemplo, com apenas três vias seria possível sinalizar todas as oitos interrupções do PC XT. Com mais uma, todas as dezesseis dos PCs atuais.
À medida que o PC foi evoluindo e novos periféricos foram sendo adicionados, praticamente todas as IRQs disponíveis foram tomadas. Num PC moderno típico, com direito a USB, não restam mais do que duas ou três IRQs pra placas adicionais, caso as placas não possam compartilhar IRQs.
Com auxílio do Windows 95 OSR2.x, do Windows 98 e dos novos Bios, as IRQs associadas a dispositivos PCI podem potencialmente ser compartilhadas. As IRQs associadas a dispositivos ISA não podem ser compartilhadas. Todas as IRQs disponíveis podem ser utilizadas tanto no barramento ISA quanto no PCI, entretanto para haver compartilhamento, uma mesma IRQ deve ser utilizada exclusivamente por dispositivos PCI.
Desde o início algumas diferenças no método de ativação das IRQs do PCI o tornou diferente. O barramento PCI não está em comunicação direta com o controlador de IRQs assim como ocorre com o ISA. Há um subsistema intermediário chamado PCI Interrupt Router ( PIR – roteador de interrupções PCI).


8 – Compartilhamento de IRQs no PCI.

Muitos dos drivers de dispositivos PCI não se importam em compartilhar IRQs entre si. O sistema operacional será o maior gerente dessas operações. Quando uma IRQ é compartilhada, as rotinas ou tarefas de tratamento associadas são consultadas segundo uma ordem hierárquica baseada na solicitação temporal ao sistema, ou seja, os drivers carregados primeiro são consultados primeiro. Cabe à rotina associada informar ao sistema operacional a IRQ era esperada e que ela já foi tradada. Caso a rotina não reconheça o pedido, então o sistema operacional o passa adiante até que uma rotina a trate. Se por infelicidade nenhum driver assumir a responsabilidade pela IRQ, o sistema simplesmente trava, afinal a função da IRQ é paralisar o sistema para realizar uma operação prioritária e cabe a rotina de tratamento restabelecer o curso normal anterior à interrupção.

domingo, 18 de setembro de 2011

A capacidade de armazenamento dos discos rígidos

Guia prático:


Unidade
Símbolo
Base 2
Base 10
Kilo
K
2^10
10^3
Mega
M
2^20
10^6
Giga
G
2^30
10^9
Tera
T
2^40
10^12
Peta
P
2^50
10^15
Exa
E
2^60
10^18

Os fabricantes utilizam a base 10 para calcular quantos bytes os HDs armazenam, mas o correto é utilizar a base 2 que os sistemas operacionais utilizam. A base 2 é a correta. É por isso que os HDs sempre tem menos capacidade de armazenamento do que o indicado pelos fabricantes. Por exemplo: os fabricantes dizem que um gigabyte tem 10^9 bytes (1.000.000.000 de bytes), mas um gigabyte tem na verdade 2^30 bytes (1.073.741.824 bytes).

A seguir as tabelas de capacidade dos sistemas de arquivo FAT16, FAT32 e NTFS:






Tamanho da Partição
Tamanho do Cluster (FAT-16)
Sistema Operacional
Até 128 MB
2 KB
DOS 5.0 e superiores
De 128 MB até 256 MB
4 KB
DOS 5.0 e superiores
De 256 MB até 512 MB
8 KB
DOS 5.0 e superiores
De 512 MB até 1 GB
16 KB
DOS 6.0 e superiores
De 1 GB até 2 GB
32 KB
DOS 6.0 superiores
De 2 GB até 4 GB
64 KB
Apenas o Windows NT

Tamanho da Partição
Tamanho do Cluster (FAT-32)
Até 256 MB
Não disponível
De 256 MB até 8 GB
4 KB
De 8 GB até 16 GB
8 KB
De 16 GB até 32 GB
16 KB
De 32 GB até 2 TB *
32 KB

Tamanho da Partição
Tamanho do Cluster (NTFS)
Sistema Operacional
Até 512 MB
512 bytes           
Todos
De 512 MB até 1 GB
1 KB
Todos
De 1 GB até 2 GB
2 KB
Todos
De 2 GB até 16 TB
4 KB
Todos menos o Windows NT até a versão 3.5
De 2 GB até 4 GB
4 KB
Windows NT até a versão 3.5 apenas
De 4 GB até 8 GB
8 KB
Windows NT até a versão 3.5 apenas
De 8 GB até 16 GB
16 KB
Windows NT até a versão 3.5 apenas
De 16 GB até 32 GB
32 KB
Windows NT até a versão 3.5 apenas
De 32 GB até 256 TB
64 KB
Windows NT até a versão 3.5 apenas

sábado, 17 de setembro de 2011

Os aquivos MP3

Os arquivos MP3 (MPEG1-Layer3) se tornaram muito populares no mundo devido à alta qualidade do áudio e ao tamanho reduzido dos arquivos, que favorece a portabilidade dos mesmos.
Mas apesar da qualidade do áudio MP3 parecer igual à qualidade de CD, isto não é verdade. Para se reduzir o tamanho dos arquivos entre 1:10 e 1:12 do tamanho original, o que acontece com o Layer3, é óbvio que é feita compressão dos dados, com a conseqüente perda de qualidade.





Através dos princípios da psico-acústica os cientistas desenvolveram um padrão de compressão que elimina as partes irrelevantes do áudio. Isso é possível devido às limitações da audição humana, que dificilmente consegue ouvir todos os sons dos 44 kHz dos CDS-DA.
Através de equipamentos de som robustos, de qualidade, é possível perceber a diferença entre som MP3 e de CDS-DA normais. Se utilizarmos um codificador (encoder) de baixa qualidade, aí é que a diferença é enorme. Por isso devemos utilizar programas de alta qualidade.

sexta-feira, 16 de setembro de 2011

Hz - O que significa?

Provavelmente você já ouviu falar que o processador de seu computador tem alguns Gigahertz de velocidade, de frequência, mas você sabe o que isso significa?





No computador existe um sinal elétrico chamado clock (relógio) que controla o funcionamento do processador; como é apenas um sinal, ou seja, um bit, só pode assumir os valores 0 e 1 (desligado/ligado). Um ciclo de clock equivale ao sinal de clock sair de 0 para 1 e de 1 para 0 novamente. Se há um ciclo de clock por segundo chamamos de um Hertz. Um processador executa uma instrução em várias etapas, e passa de uma etapa para outra sempre que o sinal de clock vai de 1 para 0 (borda de descida) ou de 0 para 1 (borda de subida). É escolhida pelos projetistas uma das duas bordas. É o que chamamos de Máquina de Estados.
Portanto se seu processador funciona por exemplo em 2.53GHz há 2.530.000.000 ciclos de clock/s (dois bilhões e quinhentos e trinta milhões de ciclos de clock por segundo). Mas o silício dos processadores tem um limite de velocidade suportada. Por isso surgiram os processadores com vários núcleos, porque a integração e velocidade de um núcleo só já chegou no limite.

sábado, 10 de setembro de 2011

Aproximação por instrumentos no Flight Simulator


Introdução: Olá, meu nome é Robson, sou piloto virtual (Flight Simulator, F-16
Multirole Fighter, Mig 29 Fulcrum, A-10 Cuba, F-22 raptor). Nesse tutorial você
aprenderá a interpretar cartas de aproximação por instrumentos (IACs). Como exemplo
utilizarei a carta de aproximação ILS para a pista 6 do aeroporto Mac Arthur em Nova
York, EUA.


Interpretação:

Observe que você tem que saber rastrear cursos e radiais de estações de navegação aérea
VOR. Você não vai se tornar um especialista em aproximações por instrumento aqui,
mesmo porque há outros tipos de aproximação, como VOR, NDB e GPS, mas poderá,
por exemplo, fazer os vôos de checagem do Flight Simulator para receber os
certificados de piloto por instrumentos, piloto comercial e piloto de linha aérea.
Na carta acima há várias informações, como freqüência ATIS (boletim meteorológico),
freqüência da torre de controle, freqüência de solo, tipos de luzes da pista, elevação da
pista (TDZE) etc, mas vamos nos concentrar na aproximação em si. Há dois perfis de
aproximação, o horizontal e o vertical, devemos nos concentrar nos dois.
Nossa aproximação começa na estação de navegação VOR Calverton (freqüência
117.2). Devemos fazer uma órbita à esquerda nesse VOR enquanto esperamos nossa vez
de pousar no curso 265 graus, como mostra o perfil horizontal. A seguir voamos 21.5
milhas náuticas a 2000 pés na radial 249 graus de Calverton até o marcador externo
(Out Marker) do ILS (Sistema de pouso por instrumentos). Esse marcador é a estação de
navegação aérea NDB Lokks (freqüência 366). Quando sobrevoamos o marcador
externo uma luz azul acende no painel e um som é emitido. Ao chegarmos ao marcador
externo fazemos curva à esquerda para o rumo 239 graus. Logo em seguida fazemos
curva à esquerda para o rumo 194 graus e em seguida curva à direita para o rumo 14
graus. A seguir interceptamos o localizador do ILS e em seguida o glideslope (rampa de
descida para a pista). A freqüência do ILS é 108.3. Ao cruzarmos o marcador externo
novamente a altitude mínima é 1800 pés na configuração local de altímetro. O rumo da
pista é 59 graus. Com mais ou menos 1 milha náutica de distância já devemos estar
vendo a pista. Se isso não acontecer temos que arremeter subindo para 500 pés e em
seguida aproando o VOR Calverton enquanto continuamos a subir para 2000 pés.
Fazemos órbita em Calverton novamente.
Durante todo o processo devemos manter um raio de 10 milhas náuticas em relação ao
marcador externo Lokks. A altitude mínima de segurança (MSA-Minimum Safe
Altitude) é de 1900 pés num raio de 25 milhas náuticas de Lokks.
Não sou piloto real, mas pessoalmente acho que essa minha interpretação é 100%
condizente com a realidade.






Bons vôos para todos.

Robson Faria.

quarta-feira, 2 de março de 2011

Como funcionam as fontes de alimentação

Todas as fontes dos computadores, sejam AT ou ATX, têm a função de preparar a energia que chega da rede elétrica para ser usada pelo sistema. Elas são formadas por quatro partes: transformador, retificador, filtro e regulador.





O transformador prepara a corrente elétrica para ser usada pela fonte de alimentação, transformando a tensão de 110 ou 220 volts em uma tensão específica. O retificador corrige a corrente de pulsos alternados que chega da rede elétrica, ou seja, transforma a corrente alternada que chega em corrente contínua, através de um conjunto de diodos. O filtro elimina a flutuação da tensão através de capacitores. E finalmente, o regulador manipula a corrente através de bobinas, fornecendo as tensões adequadas para o funcionamento dos sistemas da máquina, como 5V, 12V etc.
Vários problemas podem ser causados por fontes defeituosas, como por exemplo, motores de HDs que não aceleram, travamentos inexplicáveis etc

Simulador de vôo A-10 Cuba

O A-10 Cuba da Activision é sem dúvida um dos melhores simuladores de vôo para PCs de todos os tempos. Apesar dos gráficos deixarem a desejar, o simulador é de uma realidade incrível. Os criadores abdicaram da qualidade dos gráficos para obter em contrapartida leveza e realidade total para o programa. Além disso, os gráficos até que são bonitos, apesar da simplicidade. É um prato cheio para os entusiastas da aviação.




O A-10 é um jato bimotor turbo-fan de guerra que ficou famoso pela sua alta resistência em combate. Está é uma das coisas que o programa simula: a resistência. Você pode tomar uma rajada de metralhadora antiaérea e permanecer voando. Até mísseis na maioria das vezes não são suficientes pra derrubar o bicho, a não ser que acerte em cheio.
O realismo começa pela cabine de controle do avião, que tem quase todos os controles de uma aeronave de verdade, como, por exemplo, RPM do APU, RPM dos motores, temperatura dos motores, temperatura dos gases de escape (EGT), fluxo de combustível etc.
Há o sistema de armas, que pode ser ligado ou desligado através da chave MASTER ARM, e onde a gente seleciona a arma que será disparada, quantas serão disparadas por vez, podemos ver as armas disponíveis, podemos selecionar o modo do canhão e ver quantos cartuchos restam.
Os motores contão com extintores de incêndio que são muito úteis durante os combates, e uma luz de emergência pisca quando um motor está em chamas. Podemos também liberar todas as armas para diminuir o peso em situações de emergência. O sistema de ejeção é incrivelmente realista, a gente vê a explosão e o piloto sendo lançado para fora da aeronave em todos os detalhes.

Outra coisa bem legal é o computador de bordo, que guia o piloto automático pela rota pré-estabelecida através de GPS e auxilia na decolagem e pouso: o computador calcula a velocidade mínima de segurança de vôo (V2) através do peso do avião, e na corrida de decolagem uma luz verde acende quando a gente atinge essa velocidade, indicando que a gente já pode fazer a rolagem e subir. No pouso o computador faz a mesma coisa, calcula a velocidade ideal de toque na pista e uma luz verde acende quando essa é atingida.
Há um seletor de modo do HUD (Heads Up Display), que é a tela transparente com informações que fica na frente da cabeça do piloto. São três opções:
1 – NAV – Modo de navegação.
2 – PAV – Modo de combate com míssil.
3 – CCIP – Ponto de impacto calculado continuamente – Serve para combate com bombas, ou seja, ataque aéreo. Quando o ponto de impacto da bomba, calculado pelo computador, é igual ao ponto marcado pelo piloto no solo, o avião lança as bombas automaticamente.
O vôo é muito real, dando de 10 no Flight Simulator. A gente sente o avião ali, na mão da gente, só pilotando no programa pra saber.
A quantidade de armas diferentes disponíveis também é impressionante: mísseis ar-ar guiados por calor, mísseis ar-terra guiados por imagem, por infravermelho, por laser e por radar, bombas de 500 até 2000 libras guiadas por CCIP ou por laser, de vários tipos, como anti-tanque, anti-pista etc, inclusive tem bombas fragmentárias que se dividem em dezenas de pedaços antes de atingir o alvo, lançadores de foguetes etc. O sistema ECM (Electronic Counter Measure) serve para atrapalhar os radares inimigos, porém a gente tem que abrir mão de uma estação de armas em uma asa para colocar o equipamento do sistema referido.
O sistema SAS deixa o avião mais manobrável, permitindo que a gente faça curvas fechadas em baixa velocidade sem perder o controle, por exemplo.
O radar também é real, com a possibilidade da gente testa-lo antes das missões.
As informações dos sistemas mostram os status de todas as partes do avião, como motores, fuselagem, trem de pouso etc, como OK ou danificado.
Participe de missões sensacionais de treinamento e de guerra, como bombardear fragatas inimigas, bases, tanques, defender a base de ataque aéreo inimigo, escoltar um avião com feridos por uma rota cheia de artilharia antiaérea inimiga, bombardear uma usina nuclear fortemente protegida etc.





Por falar em artilharia antiaérea, essa parte é um show, com as chamadas metralhadoras PPP, nas quais os projeteis explodem quando chegam próximos ao avião, e as metralhadoras antiaéreas normais. O áudio é demais e o realismo o de sempre, excelente.
As contramedidas realmente funcionam nesse simulador, ao contrário de outros por aí. Quando um míssil inimigo é disparado na gente, nós podemos tentar desvia-lo através das mesmas. Elas são umas bolas brilhantes que são disparadas do avião para tentar confundir os mísseis guiados por calor.
Se uma aterrissagem de emergência for mal sucedida, o avião pode até capotar na pista, com risco de explosão. O programa simula até os amortecedores do trem de pouso, é incrível. E a realidade não se limita ao avião da gente apenas, os outros aviões também se comportam de maneira extremamente condizente com a realidade.
Isto tudo entre muitas outras coisas que dão ao programa um realismo espetacular.
Enfim, os criadores do A-10 Cuba pensaram em tudo e fizeram um simulador incrivelmente real, excelente, um dos melhores de todos os tempos. Afinal em qual outro simulador podemos voar dentro de túneis vendo os carros passando.
Infelizmente, por ser um software antigo (1996), não está mais a venda. Por isso, se encontrar esse simulador em algum lugar, não deixe de copiar, é muito legal.

segunda-feira, 28 de fevereiro de 2011

Manipulação de arquivos em linguagem Java

Depois de vários testes cheguei à conclusão que a melhor forma de manipulação de arquivos no Java é utilizar arquivos randômicos ou serialização.

Arquivos randômicos:

Como a manipulação de arquivos randômicos no Java é difícil e trabalhosa, eu criei a classe Random para fazer o trabalho pesado. É só copiar o código e colar em uma classe com o mesmo nome. Os principais métodos da classe Random são:

Construtor – Configura a classe com o nome do arquivo que deve ser aberto ou criado, com o tamanho em caracteres dos campos e com a quantidade de campos por registro. Obviamente um arquivo só pode ser manipulado com a mesma configuração com a qual foi criado.

GravarStr – Grava uma string no final do arquivo ou em algum campo que foi excluído. Os campos excluídos são marcados logicamente com um “#”. Esse método só pode ser utilizado para a criação de novos registros, ou seja, não pode ser utilizado para atualizar registros, porque ele não oferece parâmetro para a gente dizer onde um campo novo deve ser gravado. Ele grava as informações no primeiro campo vazio que encontra. A string a ser gravada não pode começar por #. Se começar por # o programa apaga esse caractere antes de gravar a string no arquivo.






GravarStringIndex – Grava uma string no campo especificado do arquivo. A numeração começa por zero. Deve ser utilizado para atualização de registros.

ApagarString – Apaga um campo em um local especificado do arquivo e coloca um “#” como primeiro caractere do campo. Esse “#” indica que o campo foi excluído e é utilizado pelos métodos GravarStr e ContarRegistros.

ContarRegistros – retorna o número de registros do arquivo. Leva em consideração sempre o primeiro campo de cada registro.

ContarCampos – retorna o número de campos do arquivo, inclusive os vazios. Pode ser utilizado para listagens com ou sem filtro. A gente coloca um While que vai até a posição atual no arquivo ficar igual ao número de campos.

AbrirArquivo – Abre o arquivo.

FecharArquivo – Fecha o arquivo.

Os métodos para gravar e ler dados numéricos utilizam o método GravarStr e fazem as conversões automaticamente, uma vez que esse método só grava strings.

Uma string nunca é gravada antes de passar pelo método tratarString. Esse método retira um # inicial se houver um e altera o tamanho da string para o tamanho configurado dos campos do arquivo. Se a string for maior corta os caracteres em excesso, se for menor completa com espaços em branco. O método lerString ignora os espaços em branco no fim das strings gerados por esse método.
Serialização:


Através da serialização podemos gravar e ler milhares de dados de um arquivo com apenas uma instrução. A serialização consiste em gravar um objeto inteiro (classe) em um arquivo. Todos os tipos primitivos, inclusive vetores de tipos primitivos, são armazenados. Porém a serialização sempre grava por cima dos dados anteriores quando o arquivo é aberto, ou seja, pra não sobrescrever, todos os objetos têm que ser gravados em uma única sessão de abertura do arquivo. Uma boa estratégia para trabalhar com serialização é criar as seguintes classes:

  • Uma classe que representa os registros, por exemplo: Produtos.
  • Uma classe que cria um vetor de objetos Produtos e manipula seus campos (variáveis) através de métodos, por exemplo: Registros.
  • Uma classe com o método main que serializa a classe Dados que contem o vetor de objetos Produtos com todos os dados.

Não há limite de quantidade de vetores de objetos diferentes em uma classe.
As duas primeiras classes que estão envolvidas na serialização precisam implementar a interface Serializable, do pacote java.io. Essa interface não declara nenhum método, apenas marca a classe como serializável. A classe que contem o método main não precisa implementar Serializable.

Instruções:

Import java.io.*;

ObjectOutputStream arquivo=new ObjectOutputStream(new FileOutputStream(“Dados.dat”));

[1]arquivo.writeObject(registros);

arquivo.close();

ObjectInputStream arquivo=new ObjectInputStream(new FileInputStream(“Dados.dat”));

Registros registros=(Registros) arquivo.readObject;

arquivo.close();


[1] registros é um objeto da classe Registros.

Esta é a classe Random:

package random;
import java.io.*;
//Copyright (C) 2008 Robson Faria Machado

//http://robsonfm.blogspot.com/
public class Random {
 private String arquivo;
 private int campos;
 private RandomAccessFile arq;
 private int camposPorRegistro;
public Random(String arquivo, int campos, int cpr) {
 super();
 this.arquivo = arquivo;
 this.campos = campos;
 camposPorRegistro=cpr;
}
 public void abrirArquivo(){
  try{
  arq=new RandomAccessFile(this.arquivo, "rw");
  }catch(Exception e){
   System.out.println("Erro ao abrir arquivo. " + e.toString());
  }
 }
public void fecharArquivo(){
if (arq!=null){
 try{
 arq.close();
 }catch(Exception e){
  System.out.println("Erro ao fechar arquivo. " + e.toString());
 }
}
}
public void gravarStr(String str){
String teste="";
int cont=0;
str=tratarString(str);
try{
do{
 arq.seek(cont * ((campos*2)+1));
 teste=String.valueOf(arq.readChar());
 //System.out.println(teste);
 if (teste.equalsIgnoreCase("#")){
  arq.seek(cont * ((campos*2)+1));
  arq.writeChars(str);
  return;
 }
 cont++;
}while(true);
}catch(EOFException eof){
try{
 arq.writeChars(str);
 return;
}catch(IOException io){
 System.out.println("Erro ao gravar dados no arquivo. " + io.toString());
}
}catch(Exception e){
 System.out.println("Erro ao gravar dados no arquivo. " + e.toString());
}
}
public void gravarStringIndex(String texto, int pos){
 try{
  arq.seek(pos * ((campos*2)+1));
  arq.writeChars(texto);
 }catch(Exception e){
  System.out.println("Erro ao gravar dados no arquivo. " + e.toString());
 }
}
 public String tratarString(String texto){
  if (texto.substring(0, 1).equalsIgnoreCase("#")){
   texto=texto.substring(1, texto.length());
  }
  if (texto.length()>campos){
   texto=texto.substring(0, campos);
   return texto;
   }
  if (texto.length()<campos){
   int p=campos-texto.length();
   for (int i=0; i<p; i++){
    texto=texto + " ";
   }
    return texto;
  }
 
  return texto;
 }
public int procurarString(String str, int campoDoRegistro){
 if (str.length()>campos){
  System.out.println("Erro: A string a ser pesquisada é maior que os campos dos registros do arquivo.");
  System.out.println("Tamanho da string: " + str.length());
  System.out.println("Tamanho dos campos: " + (campos));
  return -1;
 }
 String teste="";
 String teste2="";
 int cont=campoDoRegistro-1;
 str=tratarString(str);
 try{
 do{
  arq.seek(cont * ((campos*2)+1));
  teste=String.valueOf(arq.readChar());
  //System.out.println(teste);
  if (teste!="#"){
   teste2="";
  for (int i=0; i<campos*2; i+=2){
   arq.seek((cont * ((campos*2)+1))+i);
   teste2=teste2+arq.readChar();

  }
  if (teste2.equalsIgnoreCase(str)){
   return cont;
  }
  }
  cont+=camposPorRegistro;
 }while(true);
 }catch(EOFException eof){
 return -1;
 }catch(Exception e){
  System.out.println("Erro ao gravar dados no arquivo. " + e.toString());
 }
 return -1;
 }
public long contarRegistros(){
 long contador=0;
 int cont=0;
 String teste;
 try{
 do{
  arq.seek(cont * ((campos*2)+1));
  teste=String.valueOf(arq.readChar());
  contador++;
  if (teste.equalsIgnoreCase("#")){
   contador--;
  }
  cont+=camposPorRegistro;
 }while(true);
 }catch(EOFException eof){
 return contador;
 }catch(Exception e){
  System.out.println("Erro ao contar registros. " + e.toString());
 }
 return contador;
}
//Método contar campos, incluive os vazios.
public long contarCampos(){
 long contador=0;
 int cont=0;
 String teste;
 try{
 do{
  arq.seek(cont * ((campos*2)+1));
  teste=String.valueOf(arq.readChar());
  contador++;
  cont++;
 }while(true);
 }catch(EOFException eof){
  return contador;
 }catch(Exception e){
  System.out.println("Erro ao contar registros. " + e.toString());
 }
 return contador;
}
public String lerString(int pos){
 String stringLida="";
 try{
  arq.seek(pos * ((campos*2)+1));
  for (int i=0; i<campos*2; i+=2){
   stringLida=stringLida + arq.readChar();
   }
  return stringLida.trim();
 }catch(Exception e){
  System.out.println("Erro ao lerString. " + e.toString());
 }
 return stringLida.trim();
 }
public void apagarString(int pos){
 String vazio="#";
 vazio=tratarString(vazio);
 try{
  arq.seek(pos * ((campos*2)+1));
  arq.writeChars(vazio);

 }catch(Exception e){
  System.out.println("Erro ao lerString. " + e.toString());
 }
 }
//int, double, float, long
public void gravarInt(int valor){
 gravarStr(String.valueOf(valor));
}
public void gravarDouble(double valor){
 gravarStr(String.valueOf(valor));
}
public void gravarFloat(float valor){
 gravarStr(String.valueOf(valor));
}
public void gravarLong(long valor){
 gravarStr(String.valueOf(valor));
}
public int lerInt(int pos){
 String val="";
 val=lerString(pos);
 return Integer.parseInt(val);
}
public double lerDouble(int pos){
 String val="";
 val=lerString(pos);
 return Double.parseDouble(val);
}
public float lerFloat(int pos){
 String val="";
 val=lerString(pos);
 return Float.parseFloat(val);
}
public long lerLong(int pos){
 String val="";
 val=lerString(pos);
 return Long.parseLong(val);
}
}