[VB.net] lista file del computer

martedì 30 marzo 2010 - 11.03

marco444 Profilo | Newbie

ciao a tutti,
io utilizzo questo codice per avere la lista di tutti i file del mio computer:

Imports System.IO
Imports System.Text

Public Class formMain

Dim CountFiles As Integer ' Variabile che tiene conto del numero di files scansionati
Dim FileList As StringBuilder ' Qui memorizzo l'elenco dei files



Private Sub btnProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcess.Click
On Error Resume Next
If Directory.Exists("C:\") Then ' controllo che la directory esista

CountFiles = 0 ' azzero il contatore dei files

FileList = New StringBuilder ' Istanzio un nuovo StringBuilder

txtList.Text = "" ' pulisco la textbox

Me.Cursor = Cursors.WaitCursor ' Imposto la clessidra

ProcessDir("C:\") ' processo directory e files

txtList.Text = FileList.ToString ' Scrivo il contenuto dello stringbuilder nella textbox (elenco files)


Me.Cursor = Cursors.Arrow ' Reimposto la freccia

MessageBox.Show(CountFiles & " Files scansionati", "Scansione", MessageBoxButtons.OK, MessageBoxIcon.Information)


Else

MessageBox.Show("La directory non esiste", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

End If

End Sub

Public Sub ProcessDir(ByVal Dir As String)
On Error Resume Next
' Processa la lista dei files trovati nella directory passata
Dim fileEntries As String() = Directory.GetFiles(Dir)
For Each fileName As String In fileEntries
ProcessFile(fileName)
Next

' Processa tutte le directory trovate nella directory passata alla funzione
Dim subdirectoryEntries As String() = Directory.GetDirectories(Dir)
For Each subdirectory As String In subdirectoryEntries
ProcessDir(subdirectory)
Next

End Sub

Public Sub ProcessFile(ByVal FilePath As String)
On Error Resume Next
' processa il file

' possiamo recuperare varie informazioni sul file tramite FileInfo
' ed eventualmente inserire qui altre routine di controllo, in questo
' codice ci limitiamo soltanto ad elencare tutti i files con le sottodirectory
' Dim InfoFile As New FileInfo(FilePath)

FileList.Append(FilePath & vbCrLf) ' aggiungo il file esaminato ora alla lista

CountFiles += 1 ' incremento il numero di files



End Sub
End Class


però sulla pennetta che ha 9000 file va bene, sul mio pc, che ne ha tanti, mi da questo errore:

System.StackOverflowException non è stata gestita


non so veramente cosa fare, potete darmi una mano per favore.

Gho5t Profilo | Junior Member

ho provato questo codice e, a parte un errore di accesso negato per via della directory System Volume Information a cui non posso accedere, mi è andato alla grande e non ho avuto alcun problema... per me il problema è che nel tuo PC ci sono così tanti file che la variabile CountFiles (che è un integer) va in overflow...

http://ondotnet.com/pub/a/dotnet/2001/07/30/vb7.html
sul link c'è una tabella che ti fa vedere le dimensioni massime delle variabili...
l'integer del VB.NET è un Int32 e quindi può arrivare a 2.147.483.647
se hai più di 2 miliardi di file (è possibilissimo con un Hard Disk dalle dimensioni di 500 GB) può essere che quella variabile arriva a 2.147.483.647 e poi quando cerchi di aumentarla di 1 va in crash, ovviamente per l'overflow dei dati sullo spazio predestinato a quella variabile...
prova a cambiare il tipo da Int a Long (che sarebbe un Int64 e che può arrivare a 9.223.372.036.854.775.807, spero che ti bastino come numero... xd)

marco444 Profilo | Newbie

ci ho provato con long, l'avevo pensata anche io questa cosa, purtroppo niente, stesso problema.

Gho5t Profilo | Junior Member

a questo punto prova a mettere tutti try catch al posto di on error resume per recuperare effettivamente cosa va in overflow...
magari vai in modalità debug e metti un bel breakpoint su tutti i catch di tutte le funzioni che hai così lo intercetti bene e riesci a vedere il messaggio di errore esteso... magari se non ci capisci postalo così proviamo a vederlo insieme...
poi a me non mi viene fuori quest'errore e quindi sto andando molto a tentoni...

marco444 Profilo | Newbie

ho fatto questo:
Imports System.IO
Imports System.Text

Public Class formMain

Dim CountFiles As Long ' Variabile che tiene conto del numero di files scansionati
Dim FileList As StringBuilder ' Qui memorizzo l'elenco dei files



Private Sub btnProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcess.Click
Try
If Directory.Exists("c:\") Then ' controllo che la directory esista

CountFiles = 0 ' azzero il contatore dei files

FileList = New StringBuilder ' Istanzio un nuovo StringBuilder

txtList.Text = "" ' pulisco la textbox

Me.Cursor = Cursors.WaitCursor ' Imposto la clessidra

ProcessDir("c:\") ' processo directory e files

txtList.Text = FileList.ToString ' Scrivo il contenuto dello stringbuilder nella textbox (elenco files)


Me.Cursor = Cursors.Arrow ' Reimposto la freccia

MessageBox.Show(CountFiles & " Files scansionati", "Scansione", MessageBoxButtons.OK, MessageBoxIcon.Information)
Timer1.Enabled = False

Else

MessageBox.Show("La directory non esiste", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

End If
Catch ex As Exception
MessageBox.Show("Errore: " & ex.Message, "Funzione: Comprimi", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Public Sub ProcessDir(ByVal Dir As String)
Try
' Processa la lista dei files trovati nella directory passata
Dim fileEntries As String() = Directory.GetFiles(Dir)
For Each fileName As String In fileEntries
ProcessFile(fileName)
Next

' Processa tutte le directory trovate nella directory passata alla funzione
Dim subdirectoryEntries As String() = IO.Directory.GetDirectories(Dir)
For Each subdirectory As String In subdirectoryEntries
ProcessDir(subdirectory)
Next
Catch ex As Exception
MessageBox.Show("Errore: " & ex.Message, "Funzione: Comprimi", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

End Sub

Public Sub ProcessFile(ByVal FilePath As String)

Try

' processa il file

' possiamo recuperare varie informazioni sul file tramite FileInfo
' ed eventualmente inserire qui altre routine di controllo, in questo
' codice ci limitiamo soltanto ad elencare tutti i files con le sottodirectory
' Dim InfoFile As New FileInfo(FilePath)

FileList.Append(FilePath & vbCrLf) ' aggiungo il file esaminato ora alla lista

CountFiles += 1 ' incremento il numero di files

Catch ex As Exception
MessageBox.Show("Errore: " & ex.Message, "Funzione: Comprimi", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

End Sub


però non va bene, perchè quando legge System Volume Information oppure le cartelle inaccessibili da errore, è per questo che avevo inserito on errore resume next, come posso nascondere quell'errore con try?

ridaria Profilo | Expert

devi, per ogni cartella processata, verificare i suoi attributi, se in essi ce quello che caratterizza le cartelle inaccessibili, allora escludi queste cartelle dal loop.

La System Volume Information ha come attributo il valore 22, ma questo molto probabilmente è la somma di due o più valori dei suoi attributi.

etc ..........
Riccardo D'Aria

marco444 Profilo | Newbie

non so perchè ma così non da problemi, sembra essere tutto risolto:

Imports System.IO
Imports System.Text

Public Class formMain

Dim CountFiles As Long ' Variabile che tiene conto del numero di files scansionati
Dim FileList As StringBuilder ' Qui memorizzo l'elenco dei files



Private Sub btnProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcess.Click
Try
If Directory.Exists("c:\") Then ' controllo che la directory esista

CountFiles = 0 ' azzero il contatore dei files

FileList = New StringBuilder ' Istanzio un nuovo StringBuilder

txtList.Text = "" ' pulisco la textbox

Me.Cursor = Cursors.WaitCursor ' Imposto la clessidra

ProcessDir("c:\") ' processo directory e files

txtList.Text = FileList.ToString ' Scrivo il contenuto dello stringbuilder nella textbox (elenco files)


Me.Cursor = Cursors.Arrow ' Reimposto la freccia

MessageBox.Show(CountFiles & " Files scansionati", "Scansione", MessageBoxButtons.OK, MessageBoxIcon.Information)
Timer1.Enabled = False

Else

MessageBox.Show("La directory non esiste", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

End If
Catch ex As Exception

End Try
End Sub

Public Sub ProcessDir(ByVal Dir As String)
Try
' Processa la lista dei files trovati nella directory passata
Dim fileEntries As String() = Directory.GetFiles(Dir)
For Each fileName As String In fileEntries
ProcessFile(fileName)
Next

' Processa tutte le directory trovate nella directory passata alla funzione
Dim subdirectoryEntries As String() = IO.Directory.GetDirectories(Dir)
For Each subdirectory As String In subdirectoryEntries
ProcessDir(subdirectory)
Next
Catch ex As Exception

End Try

End Sub

Public Sub ProcessFile(ByVal FilePath As String)

Try

' processa il file

' possiamo recuperare varie informazioni sul file tramite FileInfo
' ed eventualmente inserire qui altre routine di controllo, in questo
' codice ci limitiamo soltanto ad elencare tutti i files con le sottodirectory
' Dim InfoFile As New FileInfo(FilePath)

FileList.Append(FilePath & vbCrLf) ' aggiungo il file esaminato ora alla lista

CountFiles += 1 ' incremento il numero di files

Catch ex As Exception

End Try

End Sub

Gho5t Profilo | Junior Member

certo che non ti da errori... hai tolto tutti i messaggi di errore, quindi quando si verifica l'eccezione, non fa nulla uscendo dalla funzione dove si verificava l'errore... in pratica la cartella dove incontri l'errore viene passata senza processarla...
prova ad inserire nei blocchi catch un'istruzione che salva in un file di testo il nome della cartella che sta processando in quel momento...
fallo girare diverse volte e vedi se è sempre nella stessa cartella che incontra l'errore... se è positivo hai trovato l'inghippo, altrimenti non so proprio cosa dirti...
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5