Post on 02-Aug-2020
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
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
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.
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
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:
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
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: rico@capim.art.br
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.
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.
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.
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.
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
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!
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: rico@capim.art.br
E-mail: rico@capim.art.br
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
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).
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).
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:
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: suporte@theclub.com.br