Você está na página 1de 43

 

Curso de Especialização Tecnológica


Aplicações Informáticas de Gestão

Estruturas de Dados Compostas

Doutora Ana Maria Madureira


Doutor Nuno Malheiro

Maio de 2009

FORESP – Associação Para a Formação e Especialização Tecnológica

 
   

 
 
 
 
 
 
 
 
 
 
 
 

 
 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 

ÍNDICE:
 
1. INTRODUÇÃO....................................................................................................................................... 1

2. CONCEITOS GERAIS .......................................................................................................................... 1

3. ESTRUTURAS DE DADOS COMPOSTAS........................................................................................ 2

3.1. ESTRUTURAS .................................................................................................................................... 4


3.1.1. Declaração de uma estrutura ................................................................................................ 4
3.1.2. Declaração das variáveis ...................................................................................................... 5
3.1.3. Acesso a valores de uma estrutura ........................................................................................ 6
3.1.4. Passagem de estruturas com argumentos de Funções ou Procedimentos............................. 6
3.1.5. Tipo retornado por uma função............................................................................................. 7
3.1.6. Estruturas Encaixadas........................................................................................................... 7
3.2. VECTORES DE ESTRUTURAS ............................................................................................................. 8
3.3. STREAMS ......................................................................................................................................... 9
3.3.1. O namespace System.IO ...................................................................................................... 10
3.3.2. Classe System.IO.Stream ..................................................................................................... 13
3.3.3. Entrada/Saída da Consola................................................................................................... 15
3.3.4. Redireccionar o Standard Stream........................................................................................ 19
3.3.5. Classes StreamReader e StreamWriter................................................................................ 21
3.3.6. Classes BinaryReader e BinaryWriter................................................................................. 24
3.3.7. Serialização ......................................................................................................................... 26
3.3.8. Exercícios Resolvidos .......................................................................................................... 27
3.4. EXERCÍCIOS COMPLEMENTARES .................................................................................................... 33

4. BIBLIOGRAFIA .................................................................................................................................. 35

ANEXO 1 - CLASSE CONSOLE ............................................................................................................... 36


   

 
 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 

1.  Introdução 
O  Visual  Basic  em  geral  e  a  versão  2008,  em  particular,  possui  um  conjunto  de 
características  que  visam  ajudar  tanto  o  programador  principiante  como  o  experiente  a 
desenvolver aplicações de forma simples, rápida e divertida. 
Neste contexto e no âmbito do módulo Estruturas de Dados Compostas, pretende‐se 
que, no final da frequência do módulo, os alunos sejam capazes de: 
• compreender  a  importância  das  estruturas  compostas  na  programação  de 
computadores; 
• saber quando usar/definir tipos baseados em estruturas; 
• analisar  problemas,  conceber  algoritmos  através  de  uma  abordagem  modular 
descendente  e  desenvolver  os  algoritmos  através  de  uma  metodologia  de 
programação procedimental estruturada e recorrendo a dados estruturados; 
• reconhecer  a  importância  da  utilização  de  vectores  de  estruturas  e  ficheiros 
binários; 
• reutilizar  dados  estruturados  (estruturas,  vectores  de  estruturas,  ficheiros 
binários); 
• compreender  os  algoritmos  de  manipulação  de  vectores  de  estruturas  e  
ficheiros binários; 
• codificar os programas em Visual Basic e testar as aplicações resultantes. 
Refira‐se  que  nos  exemplos  apresentados  as  aplicações  são  essencialmente  do  tipo 
consola  considerando‐se  ser  esta  a  melhor  forma  de  se  aprender  uma  linguagem  de 
programação, uma vez que o objectivo principal está nos elementos da linguagem.   

2. Conceitos Gerais 
System  é  o  namespace  de  nível  hierárquico  mais  alto  da  plataforma  .NET  possuindo 
uma quantidade muito significativa de membros, tais como: classes, estruturas, interfaces 
e  enumerações.  Contém  ainda  outros  namespaces,  como  por  exemplo  System.Lin, 
System.Collections e System.IO. 
O  tipo  de  dados  Object  é  classe  base  de  toda  a  hierarquia  da  plataforma  .NET  e  do 
Visual Basic: todos os outros tipos de dados (estruturas e classes) derivam de e podem ser 
convertidos para um Object. 
System.Collections contém várias classe que definem diversas colecções de objectos, 
incluindo listas, pilhas, filas e dicionários. 

‐ 1 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
System.IO possui classes que permitem ler e escrever para ficheiro e streams e outras 
que disponibilizam suporte a  ficheiros e directórios. 

3.   Estruturas de Dados Compostas 
Estruturas de dados e algoritmos são temas fundamentais da ciência da computação, 
sendo  utilizados  nas  mais  diversas  áreas  do  conhecimento  e  com  os  mais  diferentes 
propósitos de aplicação. Sabe‐se que algoritmos manipulam dados. Quando estes dados 
estão organizados de forma coerente, caracterizam uma forma, uma estrutura de dados. 
São  a  organização  e  os  métodos  que  manipulam  esta  determinada  estrutura  que  lhes 
conferem singularidade. As estruturas de dados são chamadas tipos de dados compostos 
que  se  dividem  em  dois:  homogéneos  (vectores  e  matrizes)  e  heterogéneos  (colecções, 
estruturas).  As  estruturas  homogéneas  referem‐se  a  conjuntos  de  dados  formados  pelo 
mesmo  tipo  de  dado  primitivo.  As  estruturas  heterogéneas  são  conjuntos  de  dados 
formados  por  tipos  de  dados  primitivos  diferentes  (colecções,  estruturas).  A  escolha  de 
uma  estrutura  de  dados  apropriada  pode  tornar  um  problema  complicado  num  de 
solução  relativamente  trivial.  A  área  de  estudo  das  estruturas  de  dados  está  em 
permanente desenvolvimento, assim como o de algoritmos. 
Podemos definir dados como os elementos sobre os quais serão efectuadas operações 
e tipo de dado como o conjunto de valores ao qual pertence um dado. Exemplos de tipos 
de dados referem‐se: inteiro, real, caracter, etc. 
Várias e diferentes classificações surgem na literatura para os tipos de dados. Uma que 
os  classifica  em:  primitivos  (não  podem  ser  decompostos,  por  exemplo:  inteiro,  real, 
lógico  e  caracter)  e  derivados  (definidos  a  partir  dos  tipos  primitivos,  por  exemplo: 
vetores, matrizes, registos, etc.).  
Os tipos de dados derivados podem ainda ser classificados em homogéneos (agrupam 
dados  primitivos  do  mesmo  tipo,  por  exemplo:  vectores,  strings  e  matrizes)  ou 
heterogéneos agrupam dados primitivos de tipos diferentes, por exemplo as colecções e 
as estruturas.  
Os tipos de dados podem ainda ser classificados em: estáticos ou dinâmicos. Os tipos 
de dados estáticos têm tamanho sempre finito, por exemplo: tipos primitivos, colecções, 
vectores  e  matrizes.  Os  tipos  de  dados  dinâmicos  têm  um  tamanho  que  pode  variar 
durante o seu tempo de vida, referem‐se: às pilhas, às  filas, às listas, deques e árvores. 
Assim sendo, define‐se uma estrutura de dados como um tipo derivado concebido com 
o objectivo de ser manipulado de forma sistemática por algoritmos.  
Surgem neste âmbito as colecções de dados que correspondem a estruturas de dados 
que  armazenam  zero  ou  mais  elementos  (dados)  relacionados  e  que  podem  ser 
manipulados  como  um  conjunto.  Uma  colecção  deve  disponibilizar  operações  para: 
adicionar dados, remover dados, actualizar dados e definir valores. 

‐ 2 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
As colecções de dados podem ainda ser classificadas em duas categorias: lineares (nas 
quais todos os elementos contidos têm um único sucessor e um único antecessor) e não 
lineares  (os  elementos  não  mantêm  uma  relação  sequencial,  mas  sim  outro  tipo  de 
ordem  entre  si,  como  por  exemplo,  hierárquica).  Enquanto  numa  colecção  linear  os 
elementos  estão  normalmente  ordenados  sequencialmente  pela  posição  (primeiro, 
segundo, terceiro, etc.), numa colecção não linear os elementos não possuem uma ordem 
posicional.  Dois  exemplos  de  colecções  lineares  no  mundo  real  são  os  sócios  de  um 
qualquer clube ou um dicionário de palavras,  as quais podem ser modeladas através de 
vectores  ou  uma  List,  ou  ainda  uma  HashTable  ou  uma  SortedList.  Por  outro  lado, 
também no mundo real, um organograma de uma empresa ou um conjunto de produtos 
são exemplos de colecções não lineares (o primeiro exemplo poderia ser modelado com 
uma árvore e o segundo com conjuntos). 
 
 
 
 
 
 
 
 
 
   
Figura  1 – Estruturas de Dados Lineares 

As  colecções  lineares  podem  ainda  ser  classificadas:  de  acesso  sequencial  e  acesso 
directo.  As  filas  (Queue)  e  as  pilhas  (Stack)  são  exemplos  de  colecções  de  acesso 
sequencial.  Os  vectores  (Array)  e  as  listas  ordenadas  (SortedList)  são  exemplos  de 
colecções de acesso directo. 
Neste  documento  teremos  por  objectivo  caracterizar  estruturas  de  dados  compostas 
lineares  de  acesso  directo,  nomeadamente,  vectores  de  estruturas  e  ficheiros.  Assim, 
abordaremos  as  principais  estruturas  de  dados  associadas  a  colecções  da  plataforma 
.NET,  para  além  de  abordar  a  classe  Collection,  definida  no  namespace 
Microsoft.VisuaIBasic. 
Por  norma,  as  variáveis  são  de  um  só  tipo  (numérico,  texto,  booleano,  etc.)  mas por 
vezes surge a necessidade de associar numa variável tipos de dados distintos. Neste caso 
define‐se  um  tipo  de  dado  composto.  Considerando  que  este  documento  pretende  ser 
um  texto  de  apoio  ao módulo  de “Estruturas  de  Dados Compostas” usaremos  vectores 
de estruturas e ficheiros.  

‐ 3 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Os  ficheiros  surgem  como  uma  colecção  externa  de  dados  que  tem  associada  uma 
estrutura de dados designada por "stream". Os ficheiros são usados para guardar grandes 
volumes de informação. 
Suponha  que  para  um  registo  de  um  carro,  é  necessário  guardar  as  seguintes 
informações: matricula, marca, ano de fabrico e o proprietário. Em vez de utilizar quatro 
variáveis  distintas  (Matricula,  Marca,  Ano_Fabrico,  Proprietario),  pode‐se  criar  um  tipo 
composto de variáveis como o exemplo abaixo: 
TIPO regCarro
Matricula texto
Marca texto
Ano_Fabrico numero
Proprietario texto
FIM TIPO

3.1. Estruturas  
Uma estrutura  é uma variável que pode conter tipos de dados diferentes ou ainda é 
um tipo de dado cujo formato é definido pelo programador. Uma estrutura fornece uma 
forma  conveniente  de  agrupar  numa  unidade  um  conjunto  de  variáveis  de  diferentes 
tipos. 
Uma  estrutura  é  uma  generalização  do  tipo  definido  pelo  utilizador  suportado  por 
versões  anteriores  do  Visual  Basic.  Em  adição  aos  campos,  as  estruturas  podem  expor 
propriedades,  métodos  e  eventos.  Uma  estrutura  pode  implementar  uma  ou  mais 
interfaces,  e  é  possível  declarar  níveis  de  acesso  individuais  para  cada  campo.  Pode 
combinar  itens  de  tipos  diferentes  para  criar  uma  estrutura  de  dados.  Uma  estrutura 
associa um ou mais elementos entre eles e com a estrutura em si.   
Estruturas  são  úteis  quando  se  deseja  que  uma  única  variável  armazene  várias 
componentes  relacionadas  de  informação.  Por  exemplo,  convém  manter  o  nome,  a 
categoria e o salário de um funcionário juntos. Poderia usar diversas variáveis para essas 
informações,  ou  você  poderia  definir  uma  estrutura  e  usá‐la  para  uma  única  variável 
funcionário.  A  vantagem  da  estrutura  torna‐se  aparente  quando  você  tem  muitos 
funcionários e, portanto, muitas instâncias da variável. 
  

3.1.1. Declaração de uma estrutura 
Os  elementos  individuais  duma  estrutura  podem  ser  variáveis  normais,  vectores, 
matrizes  ou  outras  estruturas.  Os  nomes  dos  elementos  dentro  duma  estrutura  devem 
ser  distintos,  apesar  do  nome  de  um  elemento  poder  ser  igual  ao  nome  duma  variável 
qualquer fora da estrutura. 

‐ 4 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
A  declaração  de  estruturas  é  feita  obrigatoriamente  fora  de  qualquer  subrotina  (na 
zona  de  declarações).  Os  elementos  de  uma  estrutura  podem  ser  de  qualquer  tipo, 
incluindo vectores. 
Quando  um  elemento  de  uma  estrutura  é  do  tipo  vector,  a  dimensão  do  vector  não 
deve ser definida na  declaração da estrutura; a indicação da dimensão deve ser deixada 
para mais tarde, devendo usar‐se para o efeito a instrução ReDim. 
Ao  declarar  cada  elemento  pode  ser  especificado  um  nível  de  acesso.  Por  defeito    a 
acessibilidade é Public. 
 
Sintaxe: 
Structure tipoEstrutura
Dim nomeMembro1 As tipoMembro1
Dim nomeMembro2 As tipoMembro2
. . .
End Structure
 

Exemplo: 
Structure systemInfo

Public cPU As String

Public memory As Long

Public diskDrives() As String

Public purchaseDate As Date

End Structure

3.1.2. Declaração das variáveis 
Depois de criada uma estrutura, é possível declarar variáveis no nível de procedimento 
e  no  nível  de  módulo  como  esse  tipo.  Se  se  pretender  que  uma  estrutura  seja  privada, 
esta deve ser declarada usando a palavra‐chave Private. 
 
Sintaxe: 
Dim nomeVar As tipoEstrutura

Exemplo: 
Dim sistema as systemInfo

‐ 5 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
3.1.3. Acesso a valores de uma estrutura  
Para atribuir e recuperar valores de elementos de uma variável do tipo estrutura deve 
usar‐se o operador de acesso do membro (.) entre o nome da variável de estrutura e o 
nome do elemento da seguinte forma: 
 
Sintaxe: 
nomeVar.nomeMembro

Exemplo: 
mySystem.cPU = "486"
Dim tooOld As Boolean
If yourSystem.purchaseDate < #1/1/1992# Then tooOld = True
 

3.1.4. Passagem de estruturas com argumentos de Funções ou Procedimentos  
É possível passar uma estrutura como um argumento de um procedimento ou função, 
como se ilustra a seguir:  
Dim currentCPUName As String = "700MHz Pentium compatible"

Dim currentMemorySize As Long = 256

No cabeçalho da subrotina  especifica‐se da seguinte forma: 
Public Sub fillSystem(ByRef someSystem As systemInfo)

someSystem.cPU = currentCPUName

someSystem.memory = currentMemorySize

someSystem.purchaseDate = Now

End Sub

 
    Na chamada à subrotina deve indicar‐se fillSystem (system_info) 
O  exemplo  anterior  passa  a  variável  estrutura  por  referência,  o  que  permite  que  o 
procedimento modifique os seus elementos de modo que as alterações tenham efeito no 
ponto de chamada.   
 
 
 

‐ 6 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
3.1.5. Tipo retornado por uma função 
Pode‐se retornar uma estrutura a partir de uma Function, como se ilustra a seguir:  
Dim allSystems(100) As systemInfo

Function findByDate(ByVal searchDate As Date) As systemInfo

Dim i As Integer

For i = 1 To 100

If allSystems(i).purchaseDate=searchDate Then Return

allSystems(i)

Next i

' Process error: system with desired purchase date not found.

End Function

3.1.6. Estruturas Encaixadas  
Estruturas podem conter outras estruturas, como se ilustra a seguir:  

Structure driveInfo

type As String

size As Long

End Structure

Structure systemInfo

cPU As String

memory As Long

diskDrives() As driveInfo

purchaseDate As Date

End Structure

Dim allSystems(100) As systemInfo

ReDim allSystems(1).diskDrives(3)

allSystems(1).diskDrives(0).type = "Floppy"

‐ 7 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
3.2. Vectores de Estruturas 
Os vectores são estruturas de dados lineares e estáticas, isto é, são compostos por um 
número fixo (finito) de elementos de um determinado tipo de dados. O tempo de acesso 
aos elementos de um vector é muito rápido, sendo considerado constante: o acesso aos 
elementos  é  feito  pelo  seu  índice  no  vector.  Porém,  a  remoção  de  elementos  pode  ser 
penalizadora se não for desejável que haja espaços "vazios" no meio do vector, pois nesse 
caso  é  necessário  "arrastar"  de  uma  posição  todos  os  elementos  depois  do  elemento 
removido.  Essa  é  uma  estrutura  muito  recomendada  para  casos  em  que  os  dados 
armazenados mudam pouco ao longo do tempo. 
Refira‐se no entanto a possibilidade da implementação de vectores dinâmicos. Assim 
sendo, é possível distinguir: 
• Vector  estático  contem  um  número  fixo  de  elementos  e  é  alocado  durante  o 
tempo de compilação. 
Dim a(10) As Integer
• Vector  dinâmico  é  criado  usando  técnicas  de  alocação  e  gestão  dinâmica  de 
memória e pode ser redimensionado. 
Dim a() As Integer
ReDim a(9)
 
Como referido anteriormente os elementos de um vector podem ser de qualquer tipo, 
incluindo estruturas. Assim como os elementos de uma estrutura podem ser de qualquer 
tipo, incluindo vectores ou matrizes. 
Quando  um  elemento  de  uma  estrutura  é  do  tipo  vector,  a  dimensão  do  vector  não 
deve ser definida na declaração da estrutura; a indicação da dimensão deve ser deixada 
para  mais  tarde,  devendo  usar‐se  para  o  efeito  a  instrução  ReDim,  como  se  ilustra  de 
seguida: 
Structure systemInfo
cPU As String
memory As Long
diskDrives() As String
purchaseDate As Date
End Structure
Dim mySystem As systemInfo

ReDim mySystem.diskDrives(3)

mySystem.diskDrives(0) = "1.44 MB"

‐ 8 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Dim allSystems(100) As systemInfo

ReDim allSystems(5).diskDrives(3)

allSystems(5).CPU = "386SX"

allSystems(5).diskDrives(2) = "100M SCSI"

3.3. Streams 
É  uma  colecção  externa  de  dados  que  tem  associada  uma  estrutura  de  dados 
designada  por  "stream".  Os  ficheiros  são  usados  para  guardar  grandes  volumes  de 
informação. A operação de leitura retira dados de um "stream" de entrada. A operação 
de escrita junta novos dados ao fim de um "stream" de saída [1]. 
 

Object

Stream TextReader

FileStream MemoryStream StreamReader StringReader

TextWriter
BufferedStream NetworkStream

StreamWriter StringWriter HttpWriter


CryptoStream

Legenda:
IdentedTextWriter HtmlTextWriter
Bytes Caracteres

 
Figura  2 ‐ Hierarquia de Streams, Readers e Writers 
 
Um  stream  é  uma  abstracção  de  uma  sequência  de  bytes  como,  por  exemplo,  um 
ficheiro,  um  dispositivo  de  input/output,  dados  numa  rede  ou  mesmo  um  vector  de 
dados armazenados em memória. A vantagem desta abstracção é que é possível escrever 
na  janela  de  consola  ou  num  ficheiro  de  forma  idêntica.  Esta  secção  aborda  a 
entrada/saída (Input/Output  ‐ I/O) em aplicações de consola e com ficheiros e descreve 
algumas  das  classes  e  funcionalidades  .NET  associadas  mais  importantes  que  permitem 
manipular streams. 

‐ 9 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
A  plataforma  .NET  possui  uma  grande  variedade  de  classes  para  manipular  diversos 
tipos  de  streams.  Por  exemplo,  é  possível  manipular  streams  como  uma  sequências  de 
bytes (típico de um computador), ou ainda trabalhar com classes de mais alto nível que 
trabalham com caracteres.   

3.3.1. O namespace System.IO 
O  namespace  System.IO  é  onde  residem  as  classes  que  permitem  ler  e  escrever  de 
streams e ficheiros, para além de classes que permitem realizar operações básicas sobre 
ficheiros, directórios e caminhos para ficheiros e directórios. 
Para se usar estas classes deverá incluir a seguinte declaração no início do programa: 
Imports System.IO

Tabela 1 ‐ Classe System.IO 
Classe  Descrição 
BinaryReader e BinaryWriter   Estas  classes  permitem  ler  e  escrever  tipos  de  dados 
  básicos  (Integer,  Double,  Long,  String,  ...)  como  valores 
binários com uma codificação específica. 
Directory  Disponibiliza  métodos  de  classe  (Shared)  para  criar, 
  mover e aceder a directórios e subdirectórios. 
DirectoryInfo   Disponibiliza  métodos  de  instância  para  criar,  mover  e 
aceder a directórios e subdirectórios . 
DriveInfo   Disponibiliza acesso a informação sobre drives. 
File   Disponibiliza  métodos  de  classe  (Shared)  para  criar, 
  copiar,  eliminar,  mover  e  abrir  ficheiros,  e  ajuda  na 
criação de objectos FileStream. 
Filelnfo   Disponibiliza  métodos  de  instância  para  criar,  copiar, 
  eliminar,  mover  e  abrir  ficheiros,  e  ajuda  na  criação  de 
objectos FileStream. 
FileSystemlnfo   Representa  a  classe  base  para  as  classes  Filelnfo  e 
  Directorylnfo. 
Path  Realiza  operações  em  instâncias  do  tipo  string  que 
  contêm informação sobre um caminho (path), associado 
a ficheiros ou directórios 
Stream   A  classe  Stream  é  a  classe  da  qual  derivam  todos  os 
  streams. Um stream é uma abstracção de uma sequência 
de bytes. 

‐ 10 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
StreamReader  e  Implementam,  respectivamente,  um  objecto  do  tipo 
StreamReader  TextReader  e  TextWriter  que  permitem  ler  e  escrever 
  num stream (ficheiro) de caracteres. 
StringWriter  e StringReader  Implementam,  respectivamente,  um  objecto  do  tipo 
  TextReader  e  TextWriter  que  permitem  ler  e  escrever 
num stream de caracteres em memória. 
TextReader e TextWriter   Representam  as  classes  base  para  as  classes  de  input 
  StreamReader  e  StringReader  e  output  StreamWriter  e 
StringWriter. 
 
O  namespace  System.IO  define  um  importante  conjunto  de  enumerações,  sendo  as 
mais importantes apresentadas na tabela seguinte. 
 
Tabela 2 ‐  Enumerações de System.IO 
Enumeração  Descrição 
FileAccess    Define  constantes  para  ler,  escrever,  ou  ler  e  escrever  de  um  ficheiro. 
Usada em construtores das classes File, Filelnfo e FileStream. 
FileAtributes  Define atributos para ficheiros e directórios (usada com as funções Dir, 
GetAttr e SetAttr do Visual Basic) . 
FileMode  Um  parâmetro  FileMode  é  usado  em  vários  construtores  da  classe 
FileStream e nos métodos Open das classes File e Filelnfo, especificando 
como um ficheiro é aberto. 
FileOptions  Especifica  constantes  de  ficheiros  avançadas,  usadas  na  construção  de 
um objecto FileStream. 
FileShare  Especifica  constantes  que  controlam  o  tipo  de  acesso  que  outros 
objectos FileStream podem ter ao mesmo ficheiro. 
Usado no construtor de um FileStream. 
SearchOption   Possui  constantes  que  especificam  se  a  pesquisa  deve  ocorrer  no 
directório  corrente  ou  no  directório  corrente  e  seus  sub‐directórios. 
 
Usada no método GetDirectories de objectos Directorylnfo. 
SeekOrigin   Usada  no  método  Seek  de  diversas  classes,  esta  enumeração  possui 
campos que representam os pontos de referência para posicionamento 
de streams. 
 
Associado  à  leitura  e  escrita  em  ficheiros  está  o  conceito  de  programação  robusta. 
Sempre que tentar abrir um ficheiro para leitura e/ou escrita ou tentar aceder a detalhes 

‐ 11 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
associados a ficheiros e directórios, é necessário usar o bloco Try...Catch para recolher as 
excepções associadas a estas operações. O namespace System.IO possui diversas classes 
de excepção, algumas das quais são apresentadas na tabela seguinte. 
 
Tabela 3 ‐ Classe de excepção de System.IO 
Excepção  Descrição 
DirectoryNotFoundException   Esta  excepção  é  lançada  quando  parte  de  um ficheiro  ou 
  directório não é encontrado. 
DriveNotF ound Exception   Esta  excepção  é  lançada  quando  se  tenta  aceder  a  um 
  drive que não está disponível. 
EndOfStreamException   Esta excepção é lançada quando se tenta ler depois do fim 
do ficheiro. 
FileFormatException  Esta excepção é lançada quando um stream ou ficheiro de 
input não se encontra de acordo com um determinado 
formato . 
FileNotFoundException  Esta excepção é lançada quando se tenta aceder a um 
ficheiro que não existe ou ocorre uma falha no disco. 
InvalidDataException  Esta excepção é lançada quando um stream de dados 
possui um formato inválido. 
IOException    Esta excepção é lançada quando existe um problema 
genérico de input/output. 
PathTooLongException  Esta excepção é lançada quando um nome de caminho ou 
nome de ficheiro excede o número de caracteres máximo 
definido pelo sistema 
 
A hierarquia das excepções anteriores pode ser resumida pela seguinte estrutura: 
• System.Exception 
ƒ System.SystemException 
ƒ System.FileFormatException 
ƒ System .lnvalidOataException 
ƒ System.IOException 
• System.IO.OirectoryNotFoundException 
• System.IO.OriveNotFoundException 
• System.IO.EndOfStreamException 
• System.IO.FileNotFoundException 
• System.IO.PathTooLongException 

‐ 12 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
 
De  salientar  que  o  bloco  Try...Catch  permite  testar  mais  do  que  uma  excepção,  por 
forma  a  executar  código  de  acordo  com  a  excepção  lançada.  No  entanto,  apenas  um 
bloco  Catch  é  executado.  Por  outras  palavras,  caso  se  use  outras  excepções  que  não 
apenas  a  classe  base  da  qual  todas  as  excepções  derivam  (System.Exception)  deve‐se 
começar  por  testar  excepções  mais  específicas  (como,  por  exemplo, 
System.IO.FileNotFoundException),  testando  depois  as  menos  específicas  (por  exemplo, 
System.IOException)  e  só  por  último  as  mais  genéricas  (por  exemplo, 
System.SystemException ou então System.Exception). 
Antes  de  se  entrar  em  mais  detalhes  sobre  as  operações  de  I/O  sobre  streams  e 
ficheiros,  é  importante  salientar  que  existem  streams  baseados  em  bytes  e  streams 
baseados em caracteres. Por um lado, muitos dispositivos são orientados ao byte (8 bits) 
no que diz respeito às operações de I/O. Por outro, os seres humanos comunicam através 
de caracteres, sendo que um Char ocupa 16 bits (2 bytes). 
 

3.3.2. Classe System.IO.Stream 
A  classe  Stream  é  a  classe  base  para  todos  os  streams  de  bytes.  Um  stream  é  uma 
abstracção de uma sequência de bytes como, por exemplo, um ficheiro ou um dispositivo 
de  input/output.  A  classe  Stream  e  as  classes  derivadas  (BufferedStream,  FileStream  e 
MemoryStream,  por  exemplo),  encapsulam  conceitos  associados  a  diferentes  tipos  de 
input/output,  escondendo  detalhes  ao  programador  sobre  aspectos  específicos  do 
sistema operativo ou dos dispositivos manipulados. 
O conceito de Stream envolve três operações fundamentais: 
1.  Leitura  (read)  ‐  A  leitura  de  streams  consiste  na  transferência  de  dados  de  um 
stream para uma estrutura de dados como, por exemplo, um vector de bytes. 
2.  Escrita  (write)  ‐    A  escrita  em  streams  consiste  na  transferência  de  dados  de  uma 
estrutura de dados para um stream. 
3. Posicionamento (seek) ‐ Os streams podem permitir a definição de um valor relativo 
à  posição  corrente  dentro  de  um  stream  (posição  para  leitura/escrita).  Esta  capacidade 
depende do tipo de armazenamento permanente associado ao stream. 
Dependendo  do  dispositivo  de  input/output  associado,  os  streams  podem  suportar 
apenas algumas destas capacidades. Uma aplicação pode e deve testar estas capacidades 
através  das  propriedades  CanRead,  CanWrite,  e  CanSeek.  Estas  propriedades  retornam 
um  valor  Boolean  que  indica  se  o  stream  permite  realizar  as  três  operações  acima 
descritas.  
Para ler e escrever em streams dados de diversos formatos usam‐se os métodos Read 
e Write. No caso do stream permitir definir a posição corrente, para acesso directo aos 

‐ 13 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
dados, usam‐se os métodos Seek e SetLength e as propriedades Position e Length para 
retornar e definir a posição e o comprimento do stream. 
Um  conceito  importante  associado  a  alguns  streams  é  a  técnica  de  buffering.  Esta 
técnica utiliza uma área de armazenamento temporário (por exemplo, a memória RAM) 
para melhorar o tempo de resposta de alguns streams (como, por exemplo, ficheiros em 
disco rígido). Para este tipo de stream, o método Flush pode ser usado para enviar todos 
os  dados  existentes  na  memória  temporária  (buffers)  para  o  dispositivo  de 
armazenamento permanente. 
Por  último,  depois  de  se  utilizar  um  stream  deve‐se  chamar  o  método  Close.  Este 
método faz o flush dos dados armazenados nos buffers e liberta recursos associados ao 
sistema operativo. A tabela seguinte apresenta uma selecção dos principais métodos da 
classe Stream. 
Tabela 4 ‐Métodos da classe Stream 
Método  Descrição 
BeginRead  Inicia uma leitura assíncrona. 
BeginWrite  Inicia uma escrita assíncrona. 
Close   Fecha o stream, fazendo, se necessário, o flush de todos os buffers, 
e libertando os recursos associados. 
EndWrite  Espera que uma escrita assíncrona termine. 
EndRead  Espera que uma leitura assíncrona termine. 
Flush  Envia  todos  os  dados  armazenados  nas  áreas  de  armazenamento 
temporário  (buffers)  para  o  dispositivo  de  armazenamento 
associado (ficheiro, memória, etc.). 
Read  Lê bytes do stream e avança a posição corrente de acordo com o nº 
de bytes lidos.  
ReadByte  Lê um byte dostream e avança a posição corrente um byte. 
Seek  Define  a  posição  corrente  do  stream.  Nem  todos  os  streams 
suportam esta funcionalidade.  
SetLength  Define  o  cumprimento  do  stream  truncando  ou    aumentando  o 
comprimento  do  stream,  de  acordo  com  o  tamanho  actual.  Este 
método só é suportado caso o stream suporte tanto a escrita como 
o posicionamento . 
Write   Escreve bytes no stream e avança a posição corrente de acordo com 
o número de bytes escritos . 
 
WriteByte  Escreve um byte no stream e avança a posição corrente um byte. 

‐ 14 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Na tabela seguinte são apresentadas as principais propriedades da classe Stream. 
 
Tabela 5 ‐ Propriedades da classe Stream 
Propriedade  Descrição 
CanRead   Retorna um Boolean que indica se o stream suporta leitura. 
CanSeek   Retorna  um  Boolean  que  indica  se  o  stream  suporta  a  definição  da 
posição corrente para acesso directo. 
 
CanWrite   Retorna um Boolean que indica se o stream suporta escrita. 
Length.  Retorna o número de bytes do stream 
Position   Retorna  um  valor  que  representa  a  posição  corrente  do  stream.  Se  o 
stream  permitir  o  posicionamento,  esta  propriedade  é  de  escrita, 
permitindo  o  posicionamento  numa  determinada  posição  dentro  do 
stream. 
 

3.3.3. Entrada/Saída da Consola 
A  classe  Console  tem  vindo  a  ser  usada  desde  os  primeiros  exercícios  práticos, 
nomeadamente o método de entrada ReadLine e os métodos de saída Write e WriteLine. 
A classe Console reside no namespace System e não em System.IO [1]. 
Uma  vez  que  o  namespace  System  é  importado  automaticamente  como  parte  da 
configuração  do  ambiente  de  desenvolvimento  integrado,  não  é  necessário  preceder  o 
nome da classe Console com o namespace a que pertence. 
Apesar de se ter vindo a usar a classe Console numa grande parte dos programas as 
aplicações  reais  são,  de  uma  forma  geral,  do  tipo  Windows,  com  uma  interface  gráfica 
rica,  e  não  do  tipo  consola,  baseadas  em  texto.  A  razão  de  se  utilizar  aplicações  de 
consola tem a ver com o facto de serem mais adequadas como exemplos ilustrativos do 
funcionamento da linguagem Visual Basic. 
Uma  aplicação  do  tipo  consola  realiza  o  input/output  com  base  em  três  streams 
(conhecidos como "standard streams"): um stream para a entrada de dados (input), um 
stream para a saída de dados (output) e um outro ainda para o envio de mensagens de 
erro.  As  propriedades  da  classe  Console  que  retornam  estes  streams  são, 
respectivamente, In, Out e Error. 
A propriedade In é uma instância do tipo TextReader enquanto que as propriedades 
Out e Error são instâncias do tipo TextWriter. Consequentemente, é possível aceder aos 
métodos  e  propriedades  definidos  nestas  duas  classes  (Console.In.ReadLine  e 
Console.Out.WriteLine).  Contudo,  a  situação  mais  comum  é  usar‐se  os  métodos 

‐ 15 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
disponibilizados  pela  classe  Console,  que  automaticamente  manipulam  as  propriedades 
In, Out e Error (entre outros, Console.ReadLine e Console.WriteLine). 
A  necessidade  de  um  terceiro  stream,  o  stream  de  erro  (propriedade  Console.Error) 
tem  a  ver  com  o  facto  de,  em  algumas  aplicações,  ser  importante  existirem  streams 
distintos para o output e para o envio de mensagens de erro. 
A entrada ou leituta de dados com a classe Console é conseguido com três métodos: 
Read,  ReadLine  e  ReadKey.  Os  métodos  Read  e  ReadLine  lêem,  respectivamente,  o 
próximo  carácter  e  uma  linha  de  caracteres  do  stream  de  standard  input.  O  método 
ReadKey  lê/retorna  o  próximo  carácter  ou  tecla  de  função  pressionada  pelo  utilizador 
(permite  saber  também  se  as  teclas  modificadores  Ctrl,  Shift  ou  Alt  estavam 
pressionadas).  O  programas  seguinte  ilustra  o  funcionamento  dos  métodos  Read, 
ReadLine e ReadKey. 
 
Exemplo  1: método Read() 
Module Module1
Sub Main()
' Para ler um único carácter use o método Read():
' Public Shared Function Read() As Integer.
Console.Write("Pressione um carácter seguido de ENTER: ")
' Lê um carácter e converte-o para Char.
Dim ch As Char = ChrW(Console.Read())
Console.WriteLine("O carácter pressionado foi: " & ch)
Console.Write("Pressione outro carácter seguido de ENTER: ")
' O carácter lido será SEMPRE o "carriage return" (CR).
ch = ChrW(Console.Read())
Console.WriteLine("O carácter pressionado foi: " & ch)
Console.Write("Pressione outro carácter seguido de ENTER: ")
' O carácter lido será SEMPRE o "line feed" (LF).
ch = ChrW(Console.Read())
Console.WriteLine("O carácter pressionado foi: " & ch)
Console.ReadKey()
End Sub
End Module

 
Como referido, o método Read lê o próximo carácter (um único) do stream de input. 
No  entanto,  para  que  a  leitura  seja  efectivamente  realizada,  é  necessário  pressionar  a 
tecla Enter. Uma  vez  que  a  tecla  Enter  representa  dois  caracteres  (o  "carriage  return"  ‐ 
CR,  e  o  "line  feed"  ‐  LF),  quando  se  tenta  ler  um  único  carácter  com  o  método  Read  o 
stream de input lê na realidade três caracteres. Se, de seguida, tentar ler mais caracteres 
com  o  método  Read,  os  caracteres  lidos  são,  respectivamente,  o  CR  e  LF.  O  programa 

‐ 16 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
seguinte ilustra este “problema” do método Read (de realçar que o método Read retorna 
um Integer; é necessário converter o código Unicode para um Char com a função ChrW). 
O  programa  anterior,  apresentado  no  exemplo  1,  gera  um  output  parecido  com  o 
seguinte: 
 

 
 
Note que, aparentemente, apenas um carácter foi pressionado (neste caso, o carácter 
"s"). No entanto, como a tecla Enter representa os caracteres CR e LF, o stream de input 
possui  na  realidade  três  caracteres.  O  primeiro  carácter  é  o  "s"  mas  nas  outras  duas 
leituras de caracteres com o método Read aparentemente não foram lidos caracteres, o 
que não é correcto. Os caracteres lidos foram, como referido, CR e LF. 
O método ReadLine lê uma linha de caracteres até (excluindo) a tecla Enter. O tipo de 
dados de retorno é uma String. Um exemplo de utilização deste método é o apresentado 
no programa seguinte. 
 
Exemplo  2: Ler uma string com o método Console.ReadLine() 
Module Module1
Sub Main()
' Para ler uma string de caracteres use o método ReadLine():
' Public Shared Function ReadLine() As String.
' Lê uma string.
Console.Write("Introduza uma string: ")
Dim str As String = Console.ReadLine
Console.WriteLine()
Console.WriteLine("A string introduzida foi: " & str)
Console.ReadKey()
End Sub
End Module 

‐ 17 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
A saída produzida deverá ser algo semelhante a: 
 

Por  último,  o  método  ReadKey.  Este  método  retorna  um  objecto  do  tipo 
ConsoleKeylnfo (uma estrutura). Esta estrutura possui três propriedades que descrevem a 
tecla  da  janela  de  consola  que  foi  pressionada  (o  carácter  e  o  estado  das  teclas 
modificadoras  Ctrl,  Shift  e  Alt).  O  programa  seguinte  usa  um  ciclo  controlado  por  uma 
sentinela  (tecla  Esc),  para  mostrar  o  valor  das  três  propriedades  da  estrutura 
ConsoleKeyInfo para cada tecla pressionada. 
 
Exemplo  3: Ler uma string: método Console.ReadLine() 
Imports System.Text
' Classe StringBuilder.

Module Module1
Sub Main()
' Para ler um carácter ou tecla de função use o método ReadKey():
‘Public Shared Function ReadKey() As System.ConsoleKeyInfo
' Public Shared Function ReadKey(esconder As Boolean) As
System.ConsoleKeyInfo
Console.WriteLine("Pressione uma tecla (eventualmente com
Ctrl/Alt/Shift).")
Console.Write("ESC para terminar: ")
Dim ch As ConsoleKeyInfo = Console.ReadKey()
Do While ch.Key <> ConsoleKey.Escape
Dim sb As New StringBuilder("Pressionou: ")
' Verificar as teclas modificadoras (Ctrl/Alt/Shift).
If ch.Modifiers <> 0 Then

‐ 18 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
If (ch.Modifiers And ConsoleModifiers.Control) <> 0 Then
sb.Append("CTRL+")
End If
If (ch.Modifiers And ConsoleModifiers.Alt) <> 0 Then
sb.Append("ALT+")
End If
If (ch.Modifiers And ConsoleModifiers.Shift) <> 0 Then
sb.Append("SHIFT+")
End If
End If
' Mostrar qual a tecla e qual o carácter correspondente.
sb.Append(ch.Key.ToString())
sb.AppendFormat(" (carácter '{0}').", ch.KeyChar)
' Mostrar o resultado.
Console.WriteLine()
Console.WriteLine(sb.ToString())
' Ler outro carácter.
Console.WriteLine("Pressione uma tecla (eventualmente com
Ctrl/Alt/Shift).")
Console.Write("ESC para terminar: ")
ch = Console.ReadKey()
Loop
End Sub
End Module 

3.3.4. Redireccionar o Standard Stream 
Os  standard  streams  da  classe  Console,  associados  às  propriedades  In,  Out  e  Error 
podem ser redireccionados. Por exemplo, se redireccionar os streams de input e output 
para  dois  ficheiros  em  disco,  o  seu  programa  passará  a  ler  (métodos  Read,  ReadLine  e 
ReadKey) do ficheiro especificado, enquanto que o output (métodos Write e WriteLine) 
produzido  será  enviado  também  para  o  ficheiro  especificado.  Se  redireccionar  os  três 
streams o programa poderá, num outro exemplo, ler instruções de um ficheiro em disco, 
enviar  o  output  para  uma  ligação  em  rede  e  criar  um  ficheiro  associado  ao  registo  de 
operações.  Para  se  redireccionar  os  "standard  streams"  usam‐se  os  métodos  SetIn, 
SetOut  e  SetError  da  classe  Console.  Estes  métodos  definem,  respectivamente,  as 
propriedades  Console.In,  Console.Out  e  Console.Error  de  acordo  com  o  objecto 
TextReader  (para  o  método  SetIn)  ou  TextWriter  (para  os  métodos  SetOut  e  SetError) 
especificados.  Para  recuperar,  isto  é,  anular  o  redireccionamento,  existem  os  métodos 
OpenStandardInput, OpenStandardOutput e OpenStandardError. 
Como  ilustrado  no  exemplo  seguinte,  uma  operação  como  Console.WriteLine  não 
escreve  necessariamente  na  janela  de  consola.  Se  redireccionar  o  output  para  um 

‐ 19 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
ficheiro, como neste programa, o stream por omissão (a janela de consola) será ignorada 
e o resultado será enviado para um ficheiro especificado. No final recupera‐se  o stream 
de standard output para que se possa novamente escrever na janela de consola. 
 
Exemplo  4: Redireccionar o Standard Stream 
Imports System.IO
Module Module1
Sub Main()
Try
' Cria um stream de output.
Dim swout As New StreamWriter("output.txt")
' Redirecciona o "standard output".
Console.SetOut(swout)
' Escreve no "novo" "standard output".
Console.WriteLine("{0,6}{1,6}{2,6}", "n", "n^2", "n^3")
For n As Integer = 1 To 10
Console.WriteLine("{0,6}{1,6}{2,6}", n, n ^ 2, n ^ 3)
Next
' Fecha o stream.
swout.Close()
Catch ex As Exception
Console.WriteLine("O ficheiro já existe e é só de leitura ou
o disco está cheio.")
End Try

Try
'Cria outro stream de output.
Dim swerr As New StreamWriter("log.txt")
'Redirecciona o "standard error".
Console.SetError(swerr)

Try
'A linha seguinte gera uma excepção.
Dim sr As New StreamReader("filenotfound.txt")
Catch ex As Exception
'Escreve no "standard error"(log.txt) a mensagem de erro.
Console.Error.WriteLine("Ocorreu um erro: " & ex.Message)
End Try
' Fecha o stream.
swerr.Close()
Catch ex As Exception
Console.WriteLine("O ficheiro já existe e é só de leitura ou

‐ 20 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
o disco está cheio.")
End Try

' Recupera o stream de standard output para


' que se possa novamente escrever na janela.
Dim stdOutput As New StreamWriter(Console.OpenStandardOutput)
stdOutput.AutoFlush = True
Console.SetOut(stdOutput)
Console.WriteLine("já pode escrever novamente na janela.")
Console.ReadKey()
End Sub
End Module 

3.3.5. Classes StreamReader e StreamWriter 
As  classes  StreamReader  e  StreamWriter  encapsulam  um  stream  orientado  a 
caracteres.  Estas  classes  derivam,  respectivamente,  de  TextReader  e  TextWriter.  Os 
principais  métodos  definidos  na  classe  TextReader  (e,  consequentemente,  nas  classes 
derivadas, como StreamReader e StringReader) são descritos na tabela seguinte: 
 
Tabela 6 ‐ Métodos definidos na classe TextReader 
Método  Descrição 
Close  Fecha o objecto StreamReader e o stream associado. 
Peek  Retorna o carácter seguinte sem o remover do stream. 
Read  Lê o carácter seguinte ou um conjunto de caracteres seguintes. 
ReadBlock  Lê,  no  máximo,  uma  quantidade  de  caracteres  especificados  e 
escreve  os  dados  num  buffer  especificado,  a  partir  de  um  índice 
especificado. 
ReadLine  Lê  uma  linha  de  caracteres  do  stream  corrente  e  retorna‐a  como 
uma string. 
ReadToEnd  Lê  todos  os  dados  do  stream  a  partir  da  posição  corrente  até  ao 
final do stream. 
 
Os  principais  métodos  definidos  na  classe  TextWriter  e,  consequentemente,  nas 
classes derivadas, como StreamWriter, são os listados na tabela seguinte: 
 

‐ 21 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
 
Tabela 7 ‐ Métodos definidos na classe TextWriter 
Método   Descrição 
Close  Fecha o objecto Stream associado. 
Flush  Força  todos  os  dados  armazenados  em  áreas  temporárias  (buffers)  a 
serem escritos no stream. 
Write  Overloaded. Escreve dados no stream. 
Writeline  Overloaded. Escreve dados no stream, seguidos  de um new line. 
 
Para  iniciar  um  StreamWriter  a  partir  de  um  nome  de  ficheiro  com  codificação  e 
tamanho  de  buffer  por  omissão  e  escrever  uma  string  lida  do  teclado,  pode  usar‐se  o 
seguinte excerto de código: 
Dim sw As New StrearnWriter("teste.txt")

Console.Write("Introduza urna string: ")

sw.WriteLine(Console.ReadLine)

sw.Close()

A  classe  StreamWriter  possui  sete  construtores.  Por  exemplo,  é  possível  iniciar  um 
StreamWriter a partir de uma string, como no  caso anterior, ou a partir de um objecto 
Stream  (FileStream).  Existe  ainda  a  possibilidade  de  combinar  estas  duas  possibilidades 
especificando três outros parâmetros comuns: 
• O tipo de codificação (Encoding) desejada para o stream; 
• Um  valor  Boolean  que  controla  se  se  escreve  por  cima  do  stream,  caso  já 
exista, ou, caso contrário, se se adiciona ao final do stream; 
• Um valor Integer que especifica o tamanho do buffer. 
 
Como realçado anteriormente, as operações de input/output devem ser realizadas, de 
forma  robusta,  dentro  de  um  bloco  Try...Catch.  Uma  vez  que  as  possibilidades  de 
anomalias  (excepções)  lançadas  nas  operações  de  input/output  são  diversificadas,  o 
código anterior ficaria mais robusto da seguinte forma: 
Try

Dim sw As New StrearnWriter("teste.txt")

Console.Write("Introduza urna string: ")

sw.WriteLine(Console.ReadLine)

‐ 22 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
sw.Close ()

Catch ex As Exception

Console.writeLine("Erro ao abrir/escrever no ficheiro de escrita: "


&ex.Message)

End Try

Para  se  ler  de  um  stream  deve  usar‐se  a  classe  StreamReader.  À  semelhança  do 
construtor  da  classe  StreamWriter,  para  se  criar  um  objecto  StreamReader  é  possível 
passar  o  nome  de  um  ficheiro  (string)  ou  então  um  objecto  FileStream.  Englobe  as 
operações  que  podem  lançar  excepções  dentro  de  um  bloco  Try  ...Catch.  O  seguinte 
fragmento  de  código  abre  um  StreamReader  e,  usando  um  ciclo  Do  While  ...  Loop,  lê 
todo o seu conteúdo, linha a linha, mostrando‐as na janela de consola. 
Dim str As String
‘Tenta abrir o ficheiro.
Try
Dim sr As New StreamReader{"teste.txt")
‘Tenta ler do ficheiro.
Try
str = sr.ReadLine
Do While str <> Nothing
Console.WriteLine{str)
str = sr.ReadLine
Loop
Console.WriteLine{"Erro na leitura." & vbNewLine & ex.Message)
‘Fecha o ficheiro.
sr.Close ()
Console.writeLine("Erro ao abrir/ler do ficheiro de leitura: " &
ex.Message)

Note como no fragmento de código anterior é usado um bloco Try ...Catch dentro de 
outro  bloco  Try  ...Catch.  O  primeiro  trata  a  abertura  do  ficheiro.  Caso  a  chamada  ao 
construtor  gere  um  erro,  é  mostrada  uma  mensagem  a  indicar  que  houve  um  erro  ao 
abrir  o  ficheiro.  Se  não  ocorrer  uma  anomalia,  o  programa  continua  e  tenta  ler  do 
ficheiro. Se for possível ler do ficheiro, o seu conteúdo é visualizado na janela de consola. 
Contudo,  caso  haja  um  problema  na  leitura  do  ficheiro  (impossibilidade  de  alocar 
suficiente  memória  para  o  buffer  ou  então  uma  eventual  leitura  para  além  do  fim  do 
ficheiro), é importante fechar o ficheiro (método Close), uma vez que houve sucesso na 
sua abertura. 

‐ 23 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
A questão a salientar é, portanto, a seguinte: as operações de abertura de um ficheiro 
e a sua leitura (ou escrita) devem estar, normalmente, separadas em blocos Try ...Catch 
distintos e encadeados, como ilustrado no exemplo anterior. 
Os  excertos  de  código  anterior  são  resumidos  pelo  seguinte  exemplo.  O  programa 
escreve um conjunto de linhas num StreamWriter até que o utilizador pressione a tecla 
Enter  sem  ter  introduzido  qualquer  carácter.  De  seguida  todo  o  conteúdo  do  ficheiro  é 
aberto como um objecto StreamReader e, através de um ciclo controlado pelo fim. 

3.3.6. Classes BinaryReader e BinaryWriter 
Ficheiros  binários  são  simples  sequências  de  bytes  cuja  estrutura  interna  não  é 
possível  editar  com  um  processador  de  texto.  A  sua  estrutura  interna  é  definida  e 
mantida  pelo  programador.  Este  tipo  de  ficheiros  permite  uma  maior  flexibilidade  e 
eficiência no armazenamento da informação. 
As  classes  BinaryReader  e  BinaryWriter  representam  streams  de  dados  binários, 
permitindo,  respectivamente,  ler  e  escrever  dados  em  formato  binário  e  não  num 
formato passível de ser lido por seres humanos. Este é o terceiro tipo de streams definido 
pela plataforma .NET, para além de streams de bytes e streams de caracteres. 
A classe BinaryWriter define um único método que permite escrever todos os tipos de 
dados básicos do Visual Basic: o método Write (não existe o método WriteLine). Para se 
escrever num objecto BinaryWriter um Integer, um Long, um Double e um Decimal usa‐
se sempre o mesmo método mas com argumentos dos tipos de dados que se pretendem 
escrever:  o  método  Write  está  sobrecarregado  (overloaded),  existindo  18  versões  do 
método. 
A  classe  BinaryReader  define  métodos  que  permitem  ler  todos  os  tipos  de  dados 
básicos  do  Visual  Basic.  Por  exemplo,  para  ler  uma  String,  um  Integer,  um  Long,  um 
Double  e  um  Decimal  usam‐se,  respectivamente,  os  métodos  ReadString,  Readlnt32, 
Readlnt64, ReadDouble e ReadDecimal. É possível também, com o método PeekChar, ler 
um  carácter  sem  contudo  avançar  uma  posição  (ou  seja,  o  carácter  é  retornado  mas 
mantém‐se no stream).  
Para criar um objecto BinaryReader ou BinaryWriter o construtor mais  comum recebe 
um objecto do tipo Stream (relembre que a classe Stream é uma classe abstracta, isto é, 
MustInherit,  não  sendo  portanto  possível  criar  instâncias  desta  classe).  De  uma  forma 
geral,  o  objecto  Stream  passado  ao  construtor  destas  classes  é  obtido  a  partir  do 
construtor da classe FileStream, como ilustrado no seguinte excerto de código: 
 

‘Abre um BinaryReader.
Dim br As New BinaryReader(
New FileStream ("ler.bin ", FileMode.Open) )
‘Abre um BinaryWriter.

‐ 24 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Dim bw As New BinaryWriter(
New FileStream("escrever.bin", FileMode.Create))

o programa seguinte cria um objecto BinaryWriter e escreve no stream uma String, um 
Integer  e  um  Double.  Como  referido,  a  classe  BinaryWriter  disponibiliza  um  único 
método para escrita: o método Write, que se encontra sobrecarregado (overloaded). 
De  seguida  é  criado  um  objecto  BinaryReader  associado  ao  mesmo  ficheiro  onde 
foram  gravados  os  três  dados  lidos.  Os  três  valores  guardados  no  ficheiro  são  lidos, 
através  dos  métodos  ReadString,  ReadInt32  e  ReadDouble,  e  visualizados  na  janela  de 
consola. 
 
Exemplo  5 ‐ Classes BinaryWriter e BinaryReader 
' Classes BinaryWriter e BinaryReader.
' Escrever e ler dados binários.
Imports System.IO
Module Module1
Sub Main()
' Escreve dados num BinaryWriter.
Try
' Abre um BinaryWriter.
Dim bw As New BinaryWriter(New FileStream("dados.bin",
FileMode.Create))
' Escreve uma string, um inteiro e um real.
Try
Console.Write("Introduza uma string: ")
Dim str As String = Console.ReadLine
bw.Write(str)
Console.Write("Introduza um número inteiro: ")
Dim i As Integer = CInt(Console.ReadLine)
bw.Write(i)
Console.Write("Introduza um número real: ")
Dim r As Double = CDbl(Console.ReadLine)
bw.Write(r)
Catch ex As IOException
Console.WriteLine("Erro na escrita." & vbNewLine & ex.Message)
End Try
' Fecha o stream.
bw.Close()
Catch ex As Exception
Console.WriteLine("Não foi possível abrir/escrever no ficheiro para
escrita." & vbNewLine & ex.Message)

‐ 25 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
End Try
Console.WriteLine()
' Lê dados de um BinaryReader.
Try
Abre um BinaryReader.
Dim br As New BinaryReader(New FileStream("dados.bin",
FileMode.Open))
' Le a string, o inteiro e o real.
Try
Console.WriteLine("String introduzida: " & br.ReadString())
Console.WriteLine("Número inteiro introduzido: " & br.ReadInt32())
Console.WriteLine("Número real introduzido: " & br.ReadDouble())
Catch ex As IOException
Console.WriteLine("Erro na leitura." & vbNewLine & ex.Message)
End Try

' Fecha o stream.


br.Close()
Catch ex As Exception
Console.WriteLine("Não foi possível abrir o ficheiro para
leitura." & vbNewLine & ex.Message)
End Try
Console.ReadKey()
End Sub
End Module

3.3.7. Serialização 
Serialização  é  o  processo  de  conversão  de  um  objecto,  ou  um  grafo  de  objectos 
ligados,  numa  cadeia  contígua  de  bytes.  Tal  processo  permite,  por  exemplo,  gravar  o 
estado  de  um  objecto  num  ficheiro  binário  e  recuperá‐lo  mais  tarde,  com  seu  último 
estado gravado. 
A serialização pode ser vista como um mecanismo que permite gravar um objecto num 
formato standard. É ainda visto como um método standard de propagar tipos complexos 
e, em particular, objectos. Permite escrever, para um OutputStream, um objecto e todos 
aqueles  que  ele  directa  ou  indirectamente  referencia  (grafo  de  objectos).  A  De 
serialização permite restaurar, a partir de um InputStream, um grafo de objectos 
Como exemplos de utilização referem‐se o seguintes: 
• gravar o estado de uma aplicação 

‐ 26 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
• cópia  de  objectos  de/para  o  clipboard  (ou  outro  qualquer  mecanismo  de 
transferência de objectos) 
• criação de cópias de reserva de objectos em memória 
• transmissão  de  objectos  através  de  redes  de  comunicação,  para  aplicações  que 
correm noutras máquinas 
A Framework Class Library do .NET suporta a serialização e reposição de objectos de 
forma automática e fornece vários mecanismos de auxilio à serialização proprietária. 
Identificam‐se os seguintes passos para seriar um grafo de objectos: 
1. Criação de um stream ‐ Uma stream representa o suporte físico onde o objecto vai 
ser serializado (no caso anterior em memória – System.IO.MemoryStream) 
2. Criação  de  um  Formatter  ‐  Um  formatter  é  um  tipo  que  implementa  a  interface 
System.Runtime.Serialization.IFormatter  e  que  sabe  seriar  (e  repor)  um  grafo  de 
objectos num stream. A FCL tem dois formatters:  
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter

System.Runtime.Serialization.Formatters.Soap.SoapFormatter

3. Chamar o método Serialize() do formatter passando como argumentos um 
stream e um objecto (que representa a raiz do grafo de objectos a seriar). 
Os exemplos seguintes ilustram os conceitos agora enunciados.  
 

3.3.8. Exercícios Resolvidos 
De  seguida  apresenta‐se  um  conjunto  de  exercícios  para  manipulação  de  ficheiros 
binários.  O  2º  exercício  refere‐se  ao  tratamento  de  ficheiros  binários  e  o  3º  a  ficheiros 
binários  de  acesso  directo.  Ambos  usam  um  módulo  que  trata  a  estrutura  “Pessoa”, 
apesar das definições da estrutura serem diferentes. 
 
1. Criar um módulo para o tratamento da estrutura Pessoa. Este módulo deve poder: 

a. Escrever na consola o conteúdo de uma Pessoa 
b. Criar um vector com vários objectos do tipo Pessoa 
c. Escrever na consola o conteúdo de um vector de objectos do tipo Pessoa 
 
 
 
 
 

‐ 27 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Exemplo  6 ‐ Módulo Pessoa
Module ModuloPessoa

Sub Escreve_Pessoa_Consola(ByRef p As Pessoa)


If p.activo = False Then Return
Console.WriteLine("Nome: " + p.nome)
Console.WriteLine("Morada: " + p.morada)
Console.WriteLine("Telefone: " + p.telefone + " Altura: {0,6}",
p.altura_cm)
End Sub
Sub Escreve_Lista_Pessoas_Consola(ByRef vp() As Pessoa)
Console.WriteLine("--------------------------------------------")
For i = 0 To vp.Length - 1
Escreve_Pessoa_Consola(vp(i))
Next
End Sub
Sub Cria_Uma_Pessoa(ByRef p As Pessoa)
p.nome = "nuno"
p.morada = "rua nova"
p.telefone = "+351 22 1234567"
p.altura_cm = 175
p.activo = True
End Sub
Sub Cria_Nova_Pessoa(ByRef p As Pessoa, ByVal i As Integer)
Dim s As String = " - " + i.ToString
p.nome = p.nome + s
p.morada = p.morada + s
p.telefone = p.telefone + s
p.altura_cm = p.altura_cm + i
End Sub
Sub Cria_Conjunto_Pessoas(ByRef vp() As Pessoa)
Dim p As Pessoa = Nothing
Cria_Uma_Pessoa(p)
For i = 0 To vp.Length - 1
vp(i) = p
Cria_Nova_Pessoa(vp(i), i)
Next
End Sub
End Module
 

‐ 28 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
2. Ficheiros binários de acesso directo: 

a. Crie uma Estrutura de Pessoa, com nome, morada, telefone e numero de BI, 
adequada para ser usada em Ficheiros binários de acesso directo 
(comprimento fixo). Deve incluir um campo sobre se o registo se encontra 
activo. 
b. Criar uma rotina para adicionar uma pessoa ao ficheiro. 
c. Use a rotina de 1.b) e 2.b) em conjunto para criar uma nova rotina que 
adicione um conjunto de pessoas ao ficheiro. 
d. Criar uma rotina pesquisar a pessoa cujo nome é passado como parâmetro. 
e. Criar uma rotina para mostrar todo o conteúdo do ficheiro. 
f. Criar uma rotina para eliminar logicamente uma pessoa. 
g. Criar uma rotina para eliminar fisicamente uma pessoa. 
 
Exemplo  7 ‐ Ficheiros binários de acesso directo 
Module FBinario_directo
Structure Pessoa
<VBFixedString(50)> Dim nome, morada, telefone As String
Dim altura_cm As Integer
Dim activo As Boolean
End Structure

Sub Escreve_Lista_Pessoas_Ficheiro(ByRef vp() As Pessoa)


Dim fn As Integer = FreeFile()
FileOpen(fn, "Dados.txt", OpenMode.Random, OpenAccess.Write,
,Len(vp(0)))

For i = 0 To vp.Length - 1
FilePut(fn, vp(i))
Next
FileClose(fn)
End Sub
Sub Le_Lista_Pessoas_Ficheiro(ByRef vp() As Pessoa)
Dim fn As Integer = FreeFile()
Dim i As Integer = 0
FileOpen(fn, "Dados.txt", OpenMode.Random, OpenAccess.Read, ,
Len(vp(0)))
While Not EOF(fn)
FileGet(fn, vp(i))
i = i + 1
End While

‐ 29 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
FileClose(fn)
End Sub
Function Pesquisa_Uma_Pessoa(ByVal nome As String)
Dim fn As Integer = FreeFile()
Dim p As Pessoa = Nothing
FileOpen(fn, "Dados.txt", OpenMode.Random, OpenAccess.ReadWrite,
,Len(p))
Do
FileGet(fn, p)
Loop While Not EOF(fn) And Trim(p.nome) <> nome
Dim i As Integer
If EOF(fn) And Trim(p.nome) <> nome Then i = -1 Else i = Seek(fn)
FileClose(fn)
Return i
End Function
Sub Apaga_Uma_Pessoa_Logicamente(ByVal nome As String)
Dim i = Pesquisa_Uma_Pessoa(nome)
If (i = -1) Then Return
Dim fn As Integer = FreeFile()
Dim p As Pessoa = Nothing
FileOpen(fn, "Dados.txt", OpenMode.Random, OpenAccess.ReadWrite,
,Len(p))
Seek(fn, i - 1)
FileGet(fn, p)
p.activo = False
Seek(fn, i - 1)
FilePut(fn, p)
FileClose(fn)
End Sub
Sub Apaga_Uma_Pessoa_Fisicamente(ByVal nome As String)
Dim i = Pesquisa_Uma_Pessoa(nome)
If (i = -1) Then Return
Dim fn As Integer = FreeFile()
Dim p As Pessoa = Nothing
FileOpen(fn, "Dados.txt", OpenMode.Random, OpenAccess.ReadWrite,
,Len(p))

Seek(fn, i)
While Not EOF(fn)
FileGet(fn, p)
Seek(fn, i - 1)
FilePut(fn, p)
i = i + 1

‐ 30 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Seek(fn, i)
End While
Dim pn As Pessoa = Nothing
Seek(fn, i - 1)
FilePut(fn, pn)
FileClose(fn)
End Sub

Sub Main()
Dim num_pessoas As Integer = 3
Dim vp1(num_pessoas), vp2(num_pessoas), vp3(num_pessoas) As
Pessoa
Cria_Conjunto_Pessoas(vp1)
Escreve_Lista_Pessoas_Consola(vp1)
Escreve_Lista_Pessoas_Ficheiro(vp1)
Apaga_Uma_Pessoa_Logicamente("nuno - 2")
Le_Lista_Pessoas_Ficheiro(vp2)
Escreve_Lista_Pessoas_Consola(vp2)
Apaga_Uma_Pessoa_Fisicamente("nuno - 1")
Le_Lista_Pessoas_Ficheiro(vp3)
Escreve_Lista_Pessoas_Consola(vp3)

Console.ReadKey()
End Sub
End Module

3. Ficheiros Binários .NET: 

a. Crie uma Estrutura de Pessoa, com nome, morada, telefone e numero de BI, 
adequada para ser usada em Ficheiros binários .NET (serializavel). 
b. Crie uma rotina que adicione um conjunto de pessoas ao ficheiro. 
c. Crie uma rotina que liste o conjunto de pessoas do ficheiro. 
 
 
Exemplo  8 ‐ Ficheiros Binários .NET 
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

Module FBinarios
<Serializable()> Structure Pessoa

‐ 31 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Dim nome, morada, telefone As String
Dim altura_cm As Integer
Dim activo As Integer
End Structure
Sub Escreve_Lista_Pessoas_Ficheiro(ByRef vp() As Pessoa)
Dim fs As FileStream = New FileStream("DataFile.txt",
FileMode.Create)
Dim formatter As BinaryFormatter = New BinaryFormatter()
For i = 0 To vp.Length - 1
formatter.Serialize(fs, vp(i))
Next
fs.Close()
End Sub
Sub Le_Lista_Pessoas_Ficheiro(ByRef vp() As Pessoa)
Dim fs As FileStream = New FileStream("DataFile.txt",
FileMode.Open)
Dim formatter As BinaryFormatter = New BinaryFormatter()
Dim i As Integer = 0
While fs.Length <> fs.Position
vp(i) = DirectCast(formatter.Deserialize(fs), Pessoa)
i = i + 1
End While
fs.Close()
End Sub
Sub Main()
Dim num_pessoas As Integer = 3
Dim vp1(num_pessoas), vp2(num_pessoas) As Pessoa
Cria_Conjunto_Pessoas(vp1)
Escreve_Lista_Pessoas_Consola(vp1)
Escreve_Lista_Pessoas_Ficheiro(vp1)
Le_Lista_Pessoas_Ficheiro(vp2)
Escreve_Lista_Pessoas_Consola(vp2)
Console.ReadKey()
End Sub
End Module

‐ 32 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
3.4. Exercícios Complementares 
1.    Defina  uma  estrutura  para  descrever  restaurantes.  A  estrutura  deve  armazenar  o 
nome,  endereço,  preço  médio  e  o  tipo  de  comida.  Elabore  um  programa  que  crie  um 
vector de estruturas e as funções para: 
a) Preencher o vector; 
b) Mostrar todos os restaurantes de um certo tipo de comida; 
c) Mostre qual o restaurante mais barato de um certo tipo de comida; 
d) Ordenar por ordem crescente de preço os restaurantes; 
 
2.  Defina  uma  estrutura  capaz  de  armazenar  o  nome,  o  número,  o  ano  de  entrada,  o 
curso e as cadeiras feitas (máximo de 20), por um determinado aluno. Sobre cada cadeira 
feita pelo aluno é necessário guardar informação sobre o nome da cadeira e a nota final. 
Escreva um programa que crie um vector com informação de vários alunos e as funções 
para: 
a) Acrescentar alunos ao vector; 
b) Determinar  qual  o  aluno,  de  um  determinado  curso,  com  melhor 
aproveitamento.  
c) Retornar o número de alunos, de um determinado curso, que fizeram 10 ou 
menos cadeiras em mais de cinco anos. 
  
3.  O  Dr.  Dentista  António  Desdentado  resolveu  informatizar  as  fichas  clínicas  dos  seus 
doentes e, antes de pedir autorização à Comissão de Direitos Liberdades e Garantias da 
Assembleia da Republica Portuguesa, decidiu pedir um protótipo aos alunos da disciplina 
de Al do ISEP. 
A informação relativa aos clientes que o Dr. Desdentado pretende guardar é a seguinte: 
Cliente 
  Nome 
  Telefone 
  Profissão 
  Sexo 
  Idade 
  Peso 
  Dentes (total de 32) 
    Estado (bom, razoável, perdido, tirado, desvitalizado, implante) 
    Número de tratamentos já efectuados 
    Data do próximo tratamento (e.g. 1998‐07‐22) 
    Tipo do próximo tratamento 

‐ 33 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
Suponha que os dados dos n clientes se encontram já carregados num vector global em 
memória central (máximo de 100 clientes). 
a) Defina  todas  as  estruturas  e  varáveis  globais  necessárias  à  resolução  das 
seguintes alíneas. 
b) Faça  uma  função  que  retorne  a  média  das  idades  dos  pacientes  do  Dr. 
Desdentado. 
c) Faça uma função que recebe como parâmetro uma data e escreva para o ecrã 
quais as vítimas que terão que ir ao dentista nessa data. 
d) Faça  uma  função  que  indique  qual  o  dente  mais  tratado  nos  clientes  do  Dr. 
Desdentado. 
 
4.  Com  vista  a  melhorar  a  qualidade  de  serviço,  o  restaurante  “Boa  Comida”  resolveu 
informatizar  a  informação  relativa  aos  seus  clientes.  Esta  informação  encontra‐se 
guardada num vector (máximo de 200 clientes), com o seguinte formato: 
Cliente Nome 
  Telefone 
  Profissão 
  Sexo 
  Idade 
  Pratos Consumidos (20 elementos do menu) 
    Nº de doses consumidas 
    Nº de vezes que consumiu 
    Data do último consumo(exemplo: “1998‐09‐22”) 
   
Note que os 20 pratos consumidos referem‐se à lista de 20 pratos do restaurante. 
a) Defina  as  estruturas  e  as  variáveis  globais  necessárias  è  resolução  das 
seguintes alíneas. 
b) Faça  uma  função  que  indique  qual  o  prato  preferido  dos  clientes  do 
restaurante, tendo em conta o rácio número de doses / número de vezes que 
foi consumido. 
c) Uma das potencialidades do novo sistema é conseguir prever quais os pratos 
que serão consumidos por um cliente, através do seu histórico de consumos. 
Elabore uma função que recebendo como parâmetro o nome do cliente e a 
data  actual,  gere  a  lista  de  pratos  consumidos  mais  do  que  uma  vez  pelo 
cliente.  Devem  ser  ignorados  os  pratos  consumidos  pela  última  vez  há  mais 
de um ano. 

‐ 34 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 

4. Bibliografia 
 

1. O  Guia  Prático  do  Visual  Basic  2008,  Vítor  Pereira,  ISBN:  978‐989‐615‐067‐9, 
Centro Atlântico, 2008   

2. Programação em Visual Basic .NET, Vasco Capitão, FCA (www.fca.pt) 

3. An  Introduction  to  Programming  Using  Visual  Basic  2005,  6ª  Edição,  David  I. 
Schneider, Prentice Hall 

4. Informação suplementar da Microsoft: http://msdn.microsoft.com/library. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

‐ 35 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 

Anexo 1  ‐ Classe Console 
 
A  classe  Console  representa  a  janela  do  sistema  operativo  (SO)  que  permite  a 
interacção entre este e o utilizador, através de comandos ou instruções de texto inseridas 
pelo teclado do computador. Em termos formais, representa o stream de standard input, 
output e error das aplicações em modo de consola. 
Esta classe disponibiliza membros que suportam as aplicações que leiam caracteres de 
e escrevam caracteres para a janela de consola. Não é possível herdar desta classe. 
As  chamadas  a  métodos  como  Write  e  WriteLine  em  aplicações  em  modo  Windows 
não produzem qualquer efeito. Por outro lado, aplicações sem utilizador, como aplicações 
para  um  servidor,  não  devem,  de  uma  forma  geral,  mostrar  qualquer  output  para  a 
consola. 
A seguinte tabela apresenta os métodos disponibilizados pela classe Console. 
 
 
Tabela 8 ‐ Métodos da classe Console 
Método  Descrição 
Beep   Overloaded. Toca um som através das colunas da 
  consola. 
Clear   Limpa o buffer da consola e a correspondente janela da 
  consola de toda a informação. 
MoveBufferArea   Overloaded. Copia uma área de origem especificada do buffer 
  de ecrã para uma área destino especificada. 
OpenStandard  Error Overloaded. Recupera o stream de standard error. 
OpenStandardInput  Overloaded. Recupera o stream de standard input. 
OpenStandardOutput  Overloaded. Recupera o stream de standard output. 
Read  Lê o próximo carácter do stream de standard input. 
ReadKey  Overloaded. Retorna o próximo carácter ou tecla de função 
pressionada pelo utilizador. 
ReadLine  Lê uma linha de carácteres do stream de standard input. 
ResetColor  Reinicia as cores das letras e de fundo da consolapara o mseu 
valor por omissão. 
SetBufferSize  Define a  altura  e  largura  da  área  de  buffer  do ecrã  de  acordo 
com os valores especificados. 
SetCursorPosition  Define a posição do cursor. 
SetError  Define  a  propriedade  System.Console.Error  como  sendo  o 

‐ 36 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
objecto TextWriter especificado. 
SetIn  Define a propriedade System.Console.In como sendo o objecto 
TextReader especificado. 
SetOut  Define  a  propriedade  System.Console.Out  como  sendo  o 
objecto TextWriter especificado. 
SetWindowPosition  Define  a  posição  da  janela  de  consola  relativa  ao  buffer  do 
ecrã. 
SetWindowSize  Define a altura e largura da janela de consola de acordo com os 
valores especificados. 
Write  Overloaded.  Escreve  uma  representação  texto  do  valor  ou 
valores especificados no stream de standard output. 
WriteLine  Overloaded.  Escreve  uma  representação  texto  do  valor  ou 
valores  especificados,  seguidos  do  carácter  terminador  de 
linhas, no stream de standard output. 
 
Referem‐se as seguintes propriedades da classe Console (Tabela 9). 
 
Tabela 9 – Propriedades da classe Console 
Propriedade  Descrição 
BackgroundColor  Retorna ou define a cor de fundo da consola. 
BufferHeight  Retorna‐ou define a altura da área de memória intermédia do 
ecrã (buffer) . 
BufferWidth  Retorna  ou  define  a  largura  da  área  de  memória  intermédia 
do ecrã (buffer). 
CapsLock  Retorna um valor Boolean que indica se a tecla CAPS LOCK 
está ligada ou desligada. 
CursorLeft  Retorna ou define a posição da coluna do cursor dentro da 
área de buffer 
CursorSize  Retorna ou define a altura do cursor dentro de uma célula de 
carácter. 
CursorTop  Retorna ou define a posição da linha do cursor dentro da área 
de buffer. 
CursorVisible  Retorna ou define um valor que indica se o cursor está visível. 
Error  Retorna o stream de output do standard error. 
ForegroundColor  Retorna ou define a cor das letras da consola. 

‐ 37 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 
In  Retorna o stream de standard input. 
InputEncoding  Retorna ou define a codificação que a consola usa para ler 
dados. 
KeyAvailable  Retorna um valor que indica se existe uma tecla premida 
disponível no stream de input. 
LargestWindowHeight  Retorna o maior número de linhas possível da janela de 
consola, com base no tipo de letra e resolução do ecrã 
correntes. 
LargestWindowWidth  Retorna o maior número de colunas possível da janela de 
consola, com base no tipo de letra e resolução do ecrã 
correntes. 
NumberLock  Retorna um valor Boolean que indica se a tecla LOCK está 
ligada ou desligada. 
 
Out  Retorna o stream de standard output. 
 
OutputEncoding  Retorna ou define a codificação que a consola usa para 
escrever dados. 
Title  Retorna ou define o título a mostrar na barra de títulos da 
consola. 
TreatControlCAsInput  Retorna ou define um valor que indica se a combinação 
CTRL+C é tratada como input normal ou como uma 
interrupção que é tratada pelo sistema operativo. 
WindowHeight  Retorna ou define a altura da área da janela de consola. 
WindowLeft  Retorna ou define a posição mais à esquerda da área da 
janela de consola relativa ao buffer do  
WindowTop  Retorna ou define a posição de topo da área da janela de 
consola relativa ao buffer do ecrã . 
WindowWidth  Retorna ou define a largura da janela de consola. 
 

Oexemplo seguinte ilustra o funcionamento de algumas das principais propriedades e 
métodos  da  classe  Console.  Entre  outros,  são  demonstrados  os  métodos  Beep, 
SetCursorPosition,  ReadKey  e  Clear.  Entre  as  propriedades  usadas  inclui‐se: 
ForegroundColor, CapsLock, NumberLock e CursorVisible. 

‐ 38 ‐ 
Aplicações Informáticas de Gestão 
Estruturas de Dados Compostas
 
                   www.foresp.pt 
 

Exemplo  9 ‐ Classe Console 
' Classe Console.
Module Module1
Sub Main()
' Altera a cor das letras.
Console.ForegroundColor = ConsoleColor.Green
' Emite um beep standard.
Console.Beep()
' Verifica se CapsLock e NumLock estão ligados.
If Console.CapsLock Then Console.WriteLine("CapsLock: ON")
Else Console.WriteLine("CapsLock: OFF")
End If
If Console.NumberLock Then Console.WriteLine("Num Lock: ON")
Else Console.WriteLine("Num Lock: OFF")
End If
' Define a posição do cursor na janela de consola.
Console.SetCursorPosition(5, 3)
' Escreve uma string.
Console.Write("Introduza o seu nome: ")
' Lê uma string.
Dim str As String = Console.ReadLine()
' Define o título da janela como sendo a string lida.
Console.Title = str
' Emite um beep com uma frequência de 1000 Hz
' e uma duração de 500 milissegundos.
Console.Beep(1000, 200)
' Indica que o título da janela foi alterado.
Console.SetCursorPosition(5, 3)
Console.WriteLine("O seu nome é agora o título da janela!")
' Esconde o cursor.
Console.CursorVisible = False
Console.SetCursorPosition(5, 5)
Console.WriteLine("Pressione qualquer tecla para limpar a
janela")
' Lê uma tecla sem a mostrar.
Console.ReadKey(True)
' Limpa a janela de consola.
Console.Clear()
End Sub
End Module
 

‐ 39 ‐ 

Você também pode gostar