• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Cybernavigator

[VB.NET] Criar progresso ao abrir ficheiro (e adaptado para download)

2 mensagens neste tópico

Muito bem, hoje vou fazer uma função para abrir ficheiros e mostrar uma progressbar com o que já foi aberto do ficheiro, uma label com a percentagem aberta, e outra label com os bytes que foram abertos.

Bem, a razão disto é que quando comecei a programar li um tutorial em que o homem dizia que deve ser reportado todos os acontecimentos que há num programa, pois um utilizador se um programa estiver mais de 5 segundos a processar pensa que está encravado e vai começar a carregar nas teclas à sorte, ou tentar parar o processo. Pois bem, deparei-me com esta situação quando pus o meu programa a abrir ficheiros maiores que 15 mega, demora um pouco para o vb processar. Demorei um bocado a conseguir fazer isto, mas saiu bem.

Sem mais demoras, vou deixar aqui a função e explicar passo a passo.

Para começar vamos fazer o import para facilitar na escrita da função

Imports System.IO
Imports System.Windows.Forms

Insiram isto antes do

Public Class Form1

A função vai ser colada aqui, na verdade usei duas funções, uma para a acção, e outra para reportar o quanto já foi aberto numa linguagem mais amigável para o utilizador (Mais uma vez, não é qualquer utilizador que percebe que 13,0 MB = 13.724.720 bytes, por isso vamos converter 13.724.720 bytes para 13,0 MB)

   Public Function FormatarTamanho(ByVal Tamanho As Long) As String
       Try
           Dim KB As Integer = 1024
           Dim MB As Integer = KB * KB
           ' Retorna o tamanho do ficheiro em kilobytes
           If Tamanho < KB Then
               Return (Tamanho.ToString("D") & " bytes")
          'Se o tamanho do ficheiro fôr menor que 1024 bytes, não é preciso uma conversão e então o tamanho do ficheiro é em bytes.
           Else
               Select Case Tamanho / KB
                   Case Is < 1000
                       Return (Tamanho / KB).ToString("N") & "KB"
                   'Ok aqui deveria ser 1024, mas não vamos ser picuinhas, isto foi para testar e funcionou
                   Case Is < 1000000
                       Return (Tamanho / MB).ToString("N") & "MB"
                   Case Is < 10000000
                       Return (Tamanho / MB / KB).ToString("N") & "GB"
               End Select
           End If
       Catch ex As Exception
           Return Size.ToString
       End Try
   End Function

Hehe, esta acho que é fácil de perceber, se precisarem de ajuda digam, esta função pode ser usada noutros projectos, mas vou usá-la neste para reportar o quanto já foi aberto.

    Public Function AbrirFicheiro(ByVal sFile As String, ByVal pProgress As ProgressBar, ByVal LabelDePercentagem As Label, ByVal LabelProcess As Label) As Boolean
       'Dar o resultado se já acabou ou não, não é necessário para o meu projecto ams pode dar jeito em futuros
       Dim resultado As Boolean = False
       'Fazer reset à ProgressBar e ao texto
       pProgress.Value = 0
       LabelProcess.Text = ""
       'Aqui fica o array com a informação do que já foi aberto
       Dim byteBuffer(5999) As Char
       'Declarar o que está lido, o quanto já foi lido e o tamanho do ficheiro
       Dim bytesRead As Integer
       Dim TotalBytesRead As Integer
       Dim info As New FileInfo(sFile)
       Try
           'Este é o truque, o tamanho da progressbar tem de ser igual ao tamanho (em bytes) do ficheiro
           pProgress.Maximum = info.Length
           'Aqui o sr vai abrir o ficheiro e começar a ler bytes até chegar ao fim.
           Dim sr As StreamReader = File.OpenText(sFile)
           Do
               'Ler 6000 bytes para a array bytesRead
               bytesRead = sr.Read(byteBuffer, 0, 6000)
               'Se o valor da progressbar (valor corrente) é menor que o valor total da progressbar
               'vamos continuar a somar o que já foi lido.
               If pProgress.Value + bytesRead <= pProgress.Maximum Then
                   pProgress.Value += bytesRead
                   TotalBytesRead += bytesRead
                   'Aqui vamos usar a função FormatarTamanho() para uma linguagem mais corrente.
                   LabelProcess.Text = FormatarTamanho(TotalBytesRead) & " de " & FormatarTamanho(pProgress.Maximum)
               Else
                   'Se não, está concluído e então damos o valor máximo à progressbar.
                   pProgress.Value = pProgress.Maximum
               End If
               'Refrescar os valores.
               LabelDePercentagem.Text = ((pProgress.Value * 100) \ pProgress.Maximum).ToString() & "% Concluído"
               'Isto do DoEvents é necessário para mostrar o texto, se não só vão ver a barra a crescer.
               Application.DoEvents()
           Loop Until bytesRead = 0
           'Vamos meter o resultado como verdadeiro.
           resultado = True
           sr.Close()
           'Como já fez o load do ficheiro, já fechamos o documento e vamos dar a informação final.
           LabelDePercentagem.Text = "100% Concluído"
           LabelProcess.Text = FormatarTamanho(pProgress.Maximum) & " de " & FormatarTamanho(pProgress.Maximum)
       Catch ex As Exception
           'Isto é para reportar erros (se têm dúvidas nisto do doevents() try, catch, finally, devem consultar
           'outros tutoriais primeiro
           MessageBox.Show(ex.Message)
       End Try
       'A função chegou ao fim, então damos o resultado
       Return resultado
   End Function

Para usar isto vamos abrir um projecto, e meter duas labels e uma progressbar,

vou deixar aqui a imagem.

http://newengine.trap17.com/tutorials/progresso/img1.PNG

Nota: O nome do botão é abrirficheiro2 para não dar conflito com o nome da função :cheesygrin:

Ok, então no código do butão inserimos

    Private Sub AbrirFicheiro2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AbrirFicheiro2.Click
       AbrirFicheiro("C:\Vb.net\HLTV Booking\HLTV Booking\bin\VFinal\SAM vs HardStyle - 1199398800\1269628.1269629.626916-0801032320-de_nuke.dem", ProgressBar1, lblPercentagem, lblProgresso)
   End Sub

Nota: Vocês abrem o ficheiro que quiserem, o resultado é este:

http://newengine.trap17.com/tutorials/progresso/img2.PNG

Digam lá que não manda pinta... :cheesygrin:

Bom como o prometido é devido, vou deixar aqui a outra função que fiz para fazer download de arquivos na internet.

Adicionem na parte dos imports

Imports System.Net

a função download é esta

    Public Function Download(ByVal sURL As String, ByVal pProgress As ProgressBar, ByVal LabelDePercentagem As Label, ByVal LabelProcess As Label, ByVal NomeFicheiro As String) As Boolean
       'Os comentários são iguais aos da função em cima, mas agora com cenas para a internet.
       Dim result As Boolean = False
       pProgress.Value = 0
       LabelProcess.Text = ""
       Dim lHttpWebRequest As HttpWebRequest
       Dim lHttpWebResponse As HttpWebResponse
       'Esta função vai gravar o que está a fazer download, por isso faz-se o stream e grava-se o ficheiro
       Dim lHttpWebResponseStream As Stream
       Dim lFileStream As New FileStream(NomeFicheiro, FileMode.Create)
       'Aqui o buffer vai ser mais pequeno, e dimensionado como byte, é uma pequena diferença necessária.
       Dim byteBuffer(999) As Byte
       Dim bytesRead As Integer
       Dim TotalBytesRead As Integer
       Try
           'Fazer os pedidos e receber as respostas
           lHttpWebRequest = CType(WebRequest.Create(sURL), HttpWebRequest)
           lHttpWebResponse = CType(lHttpWebRequest.GetResponse, HttpWebResponse)
           'Fazer stream das respostas
           lHttpWebResponseStream = lHttpWebRequest.GetResponse.GetResponseStream
           'Ver o tamanho do que vai ser recebido e dar esse tamanho à progressbar (tal e equal como na outra função)
           pProgress.Maximum = CType(lHttpWebResponse.ContentLength, Integer)
           Do
               'A razão pela qual o buffer é mais pequeno é porque nem toda a gente usa ligações de 8 megas 
               bytesRead = lHttpWebResponseStream.Read(byteBuffer, 0, 1000)
               'Escrever os bytes no ficheiro
               lFileStream.Write(byteBuffer, 0, bytesRead)
               If pProgress.Value + bytesRead <= pProgress.Maximum Then
                   pProgress.Value += bytesRead
                   TotalBytesRead += bytesRead
                   LabelProcess.Text = FormatarTamanho(TotalBytesRead) & " de " & FormatarTamanho(pProgress.Maximum)
               Else
                   pProgress.Value = pProgress.Maximum
               End If
               LabelDePercentagem.Text = ((pProgress.Value * 100) \ pProgress.Maximum).ToString() & "% Concluído"
               Application.DoEvents()
           Loop Until bytesRead = 0
           result = True
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       Finally
           'Fechar os streams
           lHttpWebResponseStream.Close()
           lFileStream.Close()
       End Try
       Return result
   End Function

Vamos adicionar mais um butão ao nosso projecto com o nome btnDownload

e já agora vamos usar aquilo do resultado para reportar se está concluido ou não

adicionamos o seguinte ao código

    Private Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDownload.Click
       If Download("http://newengine.trap17.com/libraryfiles.exe", ProgressBar1, lblPercentagem, lblProgresso, "c:\libraryfiles.exe") = True Then
           MsgBox("Download concluido!")
       Else
           MsgBox("Erro no download!")
       End If
   End Sub

Mais uma vez o resultado é

http://newengine.trap17.com/tutorials/progresso/img2.PNG

http://newengine.trap17.com/tutorials/progresso/img4.PNG

Bem, espero que tenham gostado.

João Lopes

Até ao próximo tutorial.

Cumpz

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Muito Obrigado pelo tutorial, estava mesmo a procura disto.

:) :wallbash:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora