20

Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando
Page 2: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Editorial

Caro leitor, Nosso colaborador mensal Hamden Vogel redigiu o artigo “Técnicas de Mapeamento de Memória Para

Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

para uma região da memória onde o próprio Windows gerencia este processo, compartilhando esta memória entre

vários processos, e controlando de forma rápida e produtiva inteiramente pelo sistema operacional. Já nosso outro

colaborador Ricardo Barbosa Crivelli nos apresenta o artigo “Instalando o Django no virtualenv” tratando da instalação

do “virtualenv” através do “virtualenvwrapper” que facilita muito o processo. Nos ensina também efetuar a criação de

um ambiente junto com o Django, executando um servidor local para testar uma aplicação esqueleto. Para encerrar a

revista, o consultor técnico Thiago Cavalheiro Montebugnoli continua dando dicas sobre a Linguagem C# com o artigo

“Trabalhando com a classe PrintDocument”. Esta classe fornece métodos e atributos para impressão de dados via

codificação, geralmente utilizada para envio de informações diretamente para impressoras, podendo ou não existir uma

visualização dos dados. Através de um exemplo prático foi implementada outra classe base auxiliar herdada da

“PrintDocument” e um método “ImprimirDocumento” o qual nos explica todas as etapas para se tratabalhar com este

tipo de tarefa.

Desejo uma ótima leitura e um forte abraço!

Marcos César Silva

Diretor Técnico

Page 3: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Instalando o Django no virtualenv

Introdução

No artigo de hoje nós iremos aprender a instalar o virtualenv através do virtualenvwrapper que facilita e

muito a instalação e torna o processo que aprendemos no artigo anterior muito mais simples e rápido. Iremos também instalar o Django em nosso ambiente de desenvolvimento, criar uma aplicação esqueleto e executá-la para que possamos visualizar em um servidor local.

O que é um ambiente de desenvolvimento?

Um ambiente de desenvolvimento é uma instalação do Django em sua máquina para que você possa desenvolver e

testar as suas aplicações antes de realizar o deploy, ou seja, antes de enviá-la para o servidor de produção.

Versatilidade

Um dos pontos fortes do Django é a sua versatilidade, pois ele funciona em vários sistemas operacionais,

suporta praticamente todos os sistemas gerenciadores de banco de dados (SGBD) atuais e permite rodar tanto em

ambientes virtuais como direto no sistema operacional.

Banco de dados

O Django, como citado acima, suporta vários bancos de dados diferentes, mas é comum você achar

informações sobre os quatro principais SGBDs que são o PostgreSQL, MySQL, Oracle e o SQLite. Quando você precisar

trabalhar com outro basta utilizar a vasta gama de bibliotecas disponibilizadas pela comunidade. No primeiro momento nós iremos trabalhar com o SQLite por ser mais simples e por salvar o banco de dados

em um único arquivo. Como ele não comporta um alto nível de concorrência (entenda-se por múltiplas transações ao

mesmo tempo), ele é recomendado para aplicações de somente-leitura ou para fins didáticos! Uma dica é, sempre que possível, utilizar o mesmo banco de dados em desenvolvimento e em produção, pois

apesar de grande parte ser abstraída, os SGBDs exigem algumas diferenças em sua configuração e execução que

podem causar conflitos durante o deploy ou desenvolvimento.

Desenvolvendo dentro de um ambiente virtual

Esta parte foi coberta no artigo do mês anterior da The Club , mas de forma resumida, iremos utilizar o

virtualenv para desenvolvimento com Django. Ele cria um ambiente virtual para que eu possa instalar somente a versão

que eu desejar do Python e as bibliotecas que serão utilizadas no projeto. Isso faz com que o meu sistema fique enxuto

e evita possíveis conflitos. Se você preferir você pode configurar todo o virtualenv como fizemos no artigo anterior, mas se preferir é

possível instala o virtualenvwrapper -win que fornece uma interface mais simples, visto que não é necessário

configurar todas as informações de ambiente manualmente.

Para instalar o virtualenvwrapper-win basta executar o comando em seu prompt:

pip3 install virtualenvwrapper-win

Page 4: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Instalando o virtualenv

Assim como o pipenv, o virualenv serve para gerenciar ambientes de desenvolvimento isolados só que ele cria

uma pasta que armazena todos os executáveis necessários para seu projeto. Isso faz com que o seu projeto tenha um

tamanho maior, mas faz com que o tempo para execução seja muito menor, além de o virtualenv ser muito mais

conhecido então a possibilidade de você encontrar documentação ou até mesmo um tutorial que utiliza os comandos

específicos do virtualenv é muito maior.

Para instalar o virtualenv execute o comando:

pip install virtualenv

A Figura 1 ilustra o processo de instalação do virtualenvwrapper-win.

Figura 1. Instalação do virtualenv no Windows 10

Criando um ambiente virtual

Agora que temos tudo instalado é hora de criar o nosso ambiente virtual com o comando mkvirtualenv.

Este comando irá criar um diretório e dentro dele instalar o seu ambiente. Para criar um ambiente você deve executar o

comando:

mkvirtualenv the_club_django

Note que ele criou um diretório com o nome the_club_django , que será o nome do nosso ambiente.

Observando o resultado é possível observar que ele instala as dependências e bibliotecas no diretório:

mkvirtualenv the_club_django

C:\Users\Avell 1843\Envs is not a directory, creating

Using base prefix 'c:\\users\\avell

1843\\appdata\\local\\programs\\python\\python36'

New python executable in

C:\Users\AVELL1~1\Envs\THE_CL~1\Scripts\python.exe

Installing setuptools, pip, wheel...done.

Page 5: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Se você é usuário Linux, OSX ou utiliza o cygwin no Windows verá que é simples verificar qual ambiente você

está trabalhando, pois o nome do ambiente aparece entre parêntesis como prefixo no terminal:

the_club_django) ubuntu@ubuntu:~$

Utilizando o ambiente

Existem vários comandos que você pode utilizar ao trabalhar com o virtualenv, mas alguns você deve saber

para facilitar a sua vida, o primeiro serve para exibir a listagem de ambientes que você possui instalado:

workon

O resultado do comando deve ser semelhante a:

workon

Pass a name to activate one of the following virtualenvs:

the_club_django

test

ifsp

capim

whatsapp_bot

telegrama_bot

image_analisys

Para executar o ambiente e isolar as suas dependências basta executar o comando:

workon nome_do_ambiente

Você pode instalar os pacotes como você faria normalmente:

pip install requests

E para desativar o ambiente basta executar o comando:

deactivate

Page 6: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Instalando o Django

Agora que temos nosso ambiente funcionando é hora de instalar o Django, para isso ative o seu ambiente e

use o pip3 para instalar o Django:

django pip3 install django

Simples não? Note que ele instalou a biblioteca e suas dependências dentro do seu ambiente, assim se

você criar outro o Django não estará instalado!

Verificando a instalação

Para verificar se o Django está instalado e rodando é possível solicitar a sua versão e caso o tudo esteja

correto você verá a mensagem com a versão ou um erro caso a biblioteca ainda não esteja instalada. É importante lembrar que o comando vai variar conforme o seu sistema operacional para o Linux e o OSX execute:

python3 -m django --version

2.1.6

E para o Windows:

py -3 -m django –version

2.1.6

O padrão dos tutoriais que você encontra na internet utilizarão a versão para Linux, ou seja, o python3, porém em

nossos artigos utilizaremos o comando para o Windows, então ser você é usuário Linux ou OSX substitua o py-3 para python3.

Criando o esqueleto da aplicação

Agora que tudo está funcionando é hora de criar o esqueleto de nossa aplicação, para isso abra seu terminal e

navegue até o diretório que você deseja hospedar sua aplicação. Vamos criar uma pasta para armazenar nossos arquivos

e entrar nela:

mkdir esqueleto_django

cd esqueleto_django

Agora vamos criar um esqueleto chamado de meusite usando a ferramenta django-admin:

django-admin startproject meusite

cd meusite

Agora vamos executar um servidor de desenvolvimento para que possamos visualizar o que está sendo

desenvolvido, para isso utilizaremos o arquivo manage.py:

Page 7: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

E:\The Club\2018-06\esqueleto_django\meusite> py -3 .\manage.py runserver

Performing system checks...

System check identified no issues (0 silenced).

You have 14 unapplied migration(s). Your project may not work properly

until you apply the migrations for app(s): admin, auth, contenttypes,

sessions.

Run 'python manage.py migrate' to apply them.

June 26, 2018 - 13:21:31

Django version 2.0.6, using settings 'meusite.settings'

Starting development server at http://127.0.0.1:8000/

Quit the server with CTRL-BREAK.

Agora que nosso servidor está funcionando abra seu navegador e acesse a url http://127.0.0.1:8000/. O

resultado deverá ser semelhante à Figura 2. Para fechar o servidor pressione Control + C.

Figura 2. Design padrão do esqueleto na versão 2 do Django

Page 8: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Conclusão

No artigo de hoje aprendemos a utilizar os conceitos trabalhados no artigo anterior da The Club e como criar

um esqueleto utilizando o Django e django-admin startproject. Aprendemos também a executar um servidor local para

desenvolvimento e teste de nossa aplicação. Agora nós podemos finalmente começar a trabalhar com essa biblioteca

incrível. Espero que tenham gostado e até a próxima!

Sobre o Autor

Ricardo Barbosa Crivelli, mais conhecido como Rico Crivelli, é formado como Bacharel em Sistemas de Informação e Licenciado em Computação pela Universidade Estadual do Norte do Paraná e pós-graduando em Informática

na Educação. Atualmente é Técnico em TI no Instituto Federal de São Paulo – Câmpus Avaré. Tem como especialidade a

linguagem PHP e o framework Symfony, apesar de adorar trabalhar com front-end e desenvolvimento mobile. Possuir as

certificações COBiT 4.1 Foundation e Delphi 2006 Developer.

E-mail: [email protected]

Page 9: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Linguagem C# - Trabalhando com a classe PrintDocument

Caro amigo leitor,

No artigo deste mês irei apresentar algumas características desta importante classe da biblioteca .NET, a classe

“PrintDocument”. Ela está presente no Namespace “System.Drawing.Printing”, o qual daremos ênfase. Para quem não

sabe, ela representa um objeto que envia a saída para a impressora, ou seja, implementamos o método “Print” da classe

“PrintDocument” invocando o evento “PrintPage”.

Em se tratando de Formulários Windows, junto com a linguagem C#, o processo de impressão é orientado por

eventos, sendo a maior parte da codificação aplicada no uso de um objeto “PrintDocument”.

Criaremos uma classe base que deriva da “PrintDocument”, contedo três propriedades auxiliares, sendo: “string[]

txt”, “int pg” e “int fora”. Teremos também um método “ImprimirPagina”, o qual irá recuperar o documento enviado,

realizando o controle de tipos de fontes, altura da linha, margens, quantidade de páginas, entre outras configurações.

No evento clique do botão iremos criar o documento via codificação permitindo uma visualização do mesmo através da

classe “PrintPreviewDialog”. Nas próximas páginas serão demonstradas todas as etapas deste pequeno exemplo de

impressão.

Hierarquia da Classe “PrintDocument”

Através da documentação da própria Microsoft, podemos conferir a hierarquia de herança da classe

“PrintDocument”.

System.Object

System.MarshalByRefObject

System.ComponentModel.Component

System.Drawing.Printing.PrintDocument

Principais Classes e Métodos utilizados

Usaremos os seguintes Namespaces:

1-) System.Drawing.Printing

- PrintDocument: Classe responsável por inicializar e definir configurações todos os campos com base

na impressora

padrão.

- PrintPage:Este evento é disparado quando a saída de impressão da página atual é necessária. - Print: Evento para Iniciar o processo de impressão do documento.

- PrintPageEventArgs: Classe responsável por Inicializar uma nova instância.

- Graphics:Propriedade para obter o objeto “Graphics” usado para pintar a página.

- MarginBounds.Left, MarginBounds.Top, MarginBounds.Bottom:Propriedades da área retangular que

representa a parte da página dentro das margens. - HasMorePages: Obtem ou define um valor que indica se uma página adicional deve ser impressa.

2-) System.Windows.Forms

- PrintDialog: Classe que permite que os usuários selecionem uma impressora e escolham quais seções

do documento imprimir de um aplicativo Windows Forms.

- PrintPreviewDialog: Classe que representa um formulário de caixa de diálogo que contém um

“PrintPreviewControl” para imprimir usando um aplicativo do Windows Forms.

Page 10: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

3-) System.Drawing

- Font: Classe que define um formato específico para texto, incluindo os atributos de estilo, tamanho e face da

fonte. - Brushes: Outra classe para definir os pincéis para todas as cores padrões.

Criando o layout do exemplo

A estrutura do nosso exemplo será bem simples. Para isto abra o Microsoft Visual Studio clicando em

“Arquivo/Novo/Projeto” para criar um projeto do tipo “Aplicativo do Windows Forms (.NET Framework)”. O formulário

deverá conter alguns “TextBoxes” para entrada de dados como: Código, Nome e Cidade, um “CheckBox” para indicar

Visualização de Impressão e por fim um “Button” para executar o código.

Na Imagem 01 teremos uma boa noção deste exemplo.

Figura 01: Formulário de exemplo.

Codificando o exemplo

Precisaremos importar alguns namespaces essenciais, segue abaixo a lista.

using System.Drawing;

using System.Drawing.Printing;

using System.Windows.Forms;

A próxima etapa será a de implementar uma classe herdada da “PrintDocument”, a qual nos dará todo o suporte

necessário para obtermos o resultado desejado. Para isso criamos a mesma denominada “ClasseDocumento” com três

atributos, sendo: “txt” um vetor que irá receber nosso texto, “pg” sendo um valor inteiro para identificar o número da

página e outro chamado “Fora” para identificar a quantidade de caracteres que caberá dentro de uma página.

Verificar a Listagem 01 completa abaixo.

Page 11: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

public class ClasseDocumento : PrintDocument

{

private string[] txt;

private int pg;

private int fora;

public string[] Txt

{

get { return txt; }

set { txt = value; } }

public int Pg

{

get { return pg; }

set{ pg = value; }

}

public int Fora

{

get { return fora; }

set { fora = value; }

}

public ClasseDocumento(string[] _txt)

{

this.Txt = _txt;

}

}

Listagem 01.

O método “ImprimirPagina” será necessário, pois o mesmo usará a classe criada anteriormente para realizar

a impressão. Ver Listagem 02.

Page 12: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

private void ImprimirPagina(object sender, PrintPageEventArgs e)

{

ClasseDocumento documento = (ClasseDocumento)sender;

using (Font fonte = new Font ("Tahoma", 10))

{

float alturaLinha = fonte.GetHeight(e.Graphics);

float x = e.MarginBounds.Left; float y =

e.MarginBounds.Top;

documento.Pg += 1;

while ((y + alturaLinha) < e.MarginBounds.Bottom &&

documento.Fora <=documento.Txt.GetUpperBound(0)) {

e.Graphics.DrawString(documento.Txt[documento.Fora],

fonte,

Brushes.Black, x, y);

documento.Fora += 1;

y += alturaLinha;

}

if (documento.Fora < documento.Txt.GetUpperBound(0))

{

e.HasMorePages = true;

}

else

{

documento.Fora = 0;

}

}

Listagem 02.

A implementação da classe “ClasseDocumento” é necessária para recuperar o documento que disparou este

evento. Na próxima linha definimos a fonte para a altura da linha. Através do método “e.MarginBounds” criamos as

variáveis necessárias para tratar a posição na página. Incrementaremos a propriedade “Pg” para identificarmos a página

que está sendo impressa. O laço imprime toda informação que cabe na página, não permitindo que o mesmo ultrapasse

a borda da margem ou a quantidade de linhas.

Page 13: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

private void btnImprimir_Click (object sender, EventArgs e)

{

string[] str = new string[100];

for (int i = 0; i < 100; i++)

{

str[i] = "Código: " + txtCodigo.Text;

str[i] = " - Nome: " + txtNome.Text;

str[i] = " - Cidade: " + txtCidade.Text;

}

PrintDocument documento = new ClasseDocumento(str);

documento.PrintPage += ImprimirPagina;

PrintDialog dialogo = new PrintDialog(); dialogo.Document

= documento;

if (dialogo.ShowDialog() == DialogResult.OK)

{

if (checkVisualizar.Checked)

{

PrintPreviewDialog preview = new PrintPreviewDialog();

preview.Document = documento; preview.ShowDialog();

}

else

{

documento.Print();

}

}

}

Listagem 03.

No evento “Click” do Button criaremos o documento e o enviaremos para impressão. A variável “str” receberá

um vetor de texto de tamanho 100. Através de um laço de repetição implementaremos 100 linhas com os valores Código,

Nome e Cidade concatenados. Neste momento usaremos a classe criada anteriormente “ClasseDocumento” passando

como parâmetro o vetor “str”. Invocaremos o evento “PrintPage” através do método “ImprimirPagina”. A classe

“PrintDialog” nos mostrará uma caixa de ferramenta responsável por escolher a impressora, caso clicar no botão OK o

documento será impresso. Não podemos esquecer do “checkBox” que nos permite visualizar o conteúdo antes de

efetuar a impressão propriamente dita. Listagem 03.

Veremos o resultado final na Imagem 02 e 03

Page 14: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Figura 02: Escolhendo a impressora.

Figura 03: Visualização e resultado da Impressão.

Conclusão

A principal intenção deste artigo foi o de proporcionar ao leitor uma ideia geral desta importante

classe denominada “PrintDocument” presente na plataforma .NET. Procurei também discorrer das classes,

métodos e propriedades mais usuais para este tipo de trabalho. Para finalizar, montamos um pequeno

exemplo envolvendo todo o conceito supracitado.

Desejo uma ótima leitura, um abraço e até o mês que vem!

Page 15: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Referências

https://msdn.microsoft.com/pt-

br/library/system.drawing.printing.printdocument(v=vs.110).aspx

Sobre o Autor Thiago Cavalheiro Montebugnoli adora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de

Botucatu – SP (FATEC), já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Como experiências profissionais mais recentes, possui em seu currículo sua atuação no Centro de Processamento de Dados da Prefeitura Municipal de Itaí-SP e atualmente compõe a equipe da Coordenadoria Tecnologia da Informação no IFSP – Instituto Federal

do Estado de São Paulo em Avaré. Além disso, é colunista mensal da Revista The Club Megazine e é consultor Técnico do The Club. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD -

Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer. E-mail para contato: [email protected]

E-mail: [email protected]

Page 16: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Técnicas de Mapeamento de Memória Para Leitura/Escrita de Arquivos

Vamos neste artigo demonstrar como podemos gravar e recuperar a gravação, na casa de milhões de linhas, e de uma

forma rápida e eficiente - utilizando o recurso de mapeamento de memória fornecido pelo próprio Windows! A finalidade é realizar o processo de manipulação de arquivos com agilidade. Foi percebido em muitos softwares um

problema muito acentuado no que diz respeito a gravação de arquivos, linha a linha, e bem como recuperar uma certa

quantidade de linhas, ou mesmo todas pra exibir em algum controle (dependendo da quantidade de registros e da memória

disponível). O recurso de mapeamento em memória é muito satisfatório no quesito velocidade, e provavelmente em muitas

situações ele vai se sobressair aos métodos tradicionais padrões do Delphi como readln e writeln - onde podem ser bem lentos

se forem arquivos grandes, como em média de 400 MB. Daí que entra o mapeamento de memória de arquivos, agilizando a

leitura e gravação da mesma forma que a padrão, mas com mais rapidez desta vez. O bom que arquivos textos e binários podem ser lidos com a mesma eficiência. Vamos demonstrar duas formas - a

padrão e a nossa - pra ler um arquivo texto.

Método tradicional:

function TForm1.ReadFile(const FileName: string):

string; var M: TFileStream; begin

M := TFileStream.Create(FileName,

fmOpenRead); try SetLength(Result, M.Size);

M.Read(Result[1], M.Size); finally

M.Free

; end;

end;

Método "Memory Mapping Files":

function TForm1.MMFileToString(const AFilename: string): string; var

hFile: THandle; hFileMap: THandle;

hiSize: DWORD; loSize: DWORD;

text: string;

view: pointer; begin

Result := '';

if AFilename = '' then

Exit;

if not FileExists(AFilename) then Exit;

{Open the file} hFile := CreateFile(PChar(AFilename), GENERIC_READ, FILE_SHARE_READ, nil,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if hFile <> INVALID_HANDLE_VALUE then

Page 17: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

begin loSize := GetFileSize(hFile, @hiSize); {File

was opened successfully, now map it:} hFileMap := CreateFileMapping(hFile, nil, PAGE_READONLY,

hiSize, loSize, 'TextForString'); if (hFileMap <> 0) then

begin if (GetLastError() = ERROR_ALREADY_EXISTS)

then begin

MessageDlg('Mapping already exists - not created.', mtWarning, [mbOk], 0);

CloseHandle(hFileMap)

end

else

begin try {File mapped successfully, now map a view of the file

into the address space:} view := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0,

0); if (view <> nil) then begin {View mapped successfully}

the address space:}

CloseHandle(hFile);

{Close file handle - as long is view is open it will persist}

SetLength(Result, loSize);

Move(view^, Result[1], loSize);

end else MessageDlg('Unable to map view of file. '

+ SysErrorMessage(GetLastError), mtWarning, [mbOk], 0);

finally

UnmapViewOfFile(view); {Close view}

CloseHandle(hFileMap); {Close mapping} end

end

end else

begin MessageDlg('Unable to create file mapping. '

+ SysErrorMessage(GetLastError),

mtWarning, [mbOk], 0); end;

end

else

begin MessageDlg('Unable to open file. ' +

SysErrorMessage(GetLastError), mtWarning, [mbOk], 0); end;

end;

O segundo método é mais complexo. É maior. Mas não se assuste. Apesar do tamanho, ele será mais

rápido que o anterior - a máxima do "tamanho não é documento" é verdade nestes casos. O que pudemos

constatar que é utilizada uma região da memória do Windows e que ela também será compartilhada entre

aplicativos (processos); o que exatamente a função CreateFileMapping do Windows faz, depois chamando a

função MapViewOfFile que mapeará a visão do arquivo dentro do endereço de memória (a visão do arquivo já

foi pré-mapeada com CreateFileMapping).

Page 18: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Figura 01 - Programa pra demonstrar MMF ("Memory Mapping Files")

Agora vamos discutir a parte mais interessante deste artigo, que será a comparação entre duas importantes

técnicas:

1. A técnica MMF;

2. A classe TSynBigTableRecord - ela é open-source; desenvolvida pela Synopse; é uma classe pra ler e gravar

arquivos grandes, prometendo agilidade nestas operações - funciona como uma "tabela", e como tal podemos fazer as

operações de incluir, editar, recuperar, etc; e ela armazena os dados normalmente como faria uma tabela de um banco

de dados comum; o que é melhor é que podemos definir "atributos" neste arquivo, pois como funciona como uma

tabela, logicamente também podemos criar os campos deles; claro que estes tipos de arquivos só poderão ser

gerenciados por esta classe devido a tantas peculiaridades específicas dele.

Como pode-se notar, a classe encapsula muitos eventos e procedimentos internamente, para que o

desenvolvedor não tenha que "reinventar a roda" toda vez que for escrever esta funcionalidade, bem como evitar

códigos desnecessários repetidos o que queremos é abstrair pra nossa classe; deixar ela fazer tudo. Basta sempre

instanciar ela e associar no seu método Grid o DBGrid a ser utilizado. Exemplo: dbGridSorter.Grid:= DBGrid1; Seguem

abaixo alguns eventos criados pela classe:

Operação TSynBigTableRecord MMF

Ler Arquivo 7 segs e 56 milisegs 2 segs e 28 milisegs

Gravar Arquivo 2 segs e 94 milisegs 1 seg e 212 milisegs

Como podemos ver, a classe TSynBigTableRecord se mostrou mais rápida nos nossos testes. Mas devemos

também notar a praticidade e a usabilidade dela. Essa classe é muito específica - ela não vai ler qualquer arquivo como

a MMF lê - ela só vai ler e gravar naqueles arquivos que ela mesma for criar e destruir. Ou seja, pra que ser a mais rápida

se ela não vai se encaixar em quase nenhum contexto? O que queremos é algo mais portável, uma solução portável pra

todas ou quase todas as nossas necessidades, e por isso a nossa solução MMF é com certeza a melhor, pois não fica

devendo em muito a outra; continuando a ser rápida e prática; não precisa de arquivos a mais (na SynBigTableRecord

são necessários o acréscimo de mais 4 arquivos pra adicionar no projeto e compilar).

Page 19: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

FN := 'c:\tempFile2.dat'; sw := TStopWatch.Create;

sw.Start;

try T := TSynBigTableRecord.Create(FN,'TableName');

T.AddField('LineId',tftInt64,[tfoIndex,

tfoUnique]); T.AddField('LineContents',tftWinAnsi);

T.AddFieldUpdate;

fielID := T.Table['LineId'];

fieldContents := T.Table['LineContents']; data.Init(T.Table);

for k := 0 to StrToInt(edtLoop.Text) do

begin

data.SetFieldValue(fielID, k); //more faster than:

data.Field['Line'] := strList.Strings[i]; data.SetFieldValue(fieldContents, edtValue.Text); //more faster than:

data.Field['Number'] := lineCounter;

T.RecordAdd(data);

end; T.UpdateToFile;

sw.Stop; memoResult.Lines.Add('Elapsed ' +

Self.FormatMillisecondsToDateTime(sw.ElapsedMilliseconds)); finally

FreeAndNil(sw); T.UpdateToFile;

end;

end;

{ ... }

var

MapFile : TMappedFile;

InfoFile: PLineStructArray;

i : Integer;

begin

MapFile := TMappedFile.Create('c:\tempFile.dat'); try MapFile.MapFile('c:\tempFile.dat'); InfoFile :=

PLineStructArray(MapFile.Content);

for i := StrToInt(edtFrom.Text) to StrToInt(edtTo.Text) do

memoResult.Lines.Add(Format('%d: %s', [i, InfoFile[i].LineContents]));

Código-Fonte da gravação de arquivo texto com a classe TSynBigTableRecord e um trecho do código fonte para ler um arquivo via MMF.

Mostramos as duas técnicas e como elas podem ser úteis em ambas as situações. Mas para isso vamos fazer um

outro comparativo abaixo para entender melhor:

Page 20: Editorial - The Club - O maior clube de programadores do ... · Leitura/Escrita de Arquivos”, o qual ele nos ensina como implementar de forma eficiente o recurso de leitura e mapeando

Operação TSynBigTableRecord MMF

Vantagem! Funciona com quase

Desvantagem! Precisa conhecer os todos os arquivos e não precisa de nenhum

métodos desta classe; framework conhecimento fora as funções da própria

Ler e Gravar Arquivo MMF. Só não vai funcionar se os arquivos específico; os arquivos só abrem com esta

forem mais que 500MB, por exemplo. classe e nenhuma outra.

Como usa memória, então vai depender

dela pra funcionar.

Vantagem! É muito rápido seu

Vantagem! Ela é muito prática e

Praticidade eficiente. Sua velocidade é muito superior processamento.

que a classe TFileStream, por exemplo.

Desvantagem! Tem que adicionar 4 arquivos pro projeto em questão, Vantagem! A MMF vem de funções

"engordando" ainda mais o projeto e da API Kernel32 do Windows; então só vai

Empregabilidade conseqüentemente onerando mais a utilizar as DLL´s do próprio Windows; sem

memória - em projetos grandes isso pode onerar o tamanho ou memória do

ser demasiadamente custosa sua executável do projeto.

participação.

Conclusão

Portanto, quem ganhou agora?? Podemos ver que a MMF é a vencedora!

A não ser que você deseja manusear arquivos específicos que só seu programa conheça e mais ninguém, você

vai escolher naturalmente a MMF em praticamente tudo.

Vamos discutir depois em outros artigos novas utilidades utilizando MMF, como compartilhando informações

entre vários aplicativos através da memória compartilhada.

Portanto, use com moderação, pois a memória não é infinita. Para arquivos realmente na casa dos GB será

necessária outra técnica que já discuti em outros artigos, que é a técnica de ler e gravar em arrays a posição dos offsets

do arquivo e imprimir em um controle no tipo virtual, como um TListView, por exemplo (também pode ser um TListBox).

Bons estudos e até a próxima!

Sobre o Autor

Hamden Vogel, Consultor TheClub

E-mail: [email protected]