Methode try en cath

Status
Niet open voor verdere reacties.

ferentuske

Gebruiker
Lid geworden
5 okt 2013
Berichten
78
Waar moet ik mijn try en cath zetten want als ik hem in mijn methode zet zegt hij dat hij geen return waarde meer heeft als ik hem over mijn methode zet krijg ik overal fouten. Het gaat over de methode scanfiles

Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PE2.Events.Directorycalc.Lib
{
   public class DirectoryCalculator
    {
       public string pad;


       public int scanFiles()
       {
         


               DirectoryInfo dir = new DirectoryInfo(pad);
               FileInfo[] bestanden = dir.GetFiles("*.*", SearchOption.AllDirectories);
               int CountBestanden = bestanden.Length;

               return CountBestanden;
         

           }
       
   
       public int scanFolder()
       {
           DirectoryInfo dir = new DirectoryInfo(pad);
           DirectoryInfo[] mappen = dir.GetDirectories("*.*", SearchOption.AllDirectories);
           int Countmappen = mappen.Length;
           return Countmappen;
           
       }

    }
}
 
Je kunt try catch-en in de method en 0 returnen (maar dan weet je niet of er 0 bestanden zijn of dat er een fout was) of try catch-en waar je de method gebruikt zoals hieronder:

Code:
public void Method
{
	try
	{
		DirectoryCalculator calculator = new DirectoryCalculator();
		calculator.Path = "C:\Folder";
		int fileCount = calculator.ScanFiles()
	}
	catch(Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}
 
momenteel werkt dit

Code:
public int scanFiles()
       {
           int CountBestanden;
           try
           {
               DirectoryInfo dir = new DirectoryInfo(pad);



               FileInfo[] bestanden = dir.GetFiles("*.*", SearchOption.AllDirectories);
               CountBestanden = bestanden.Length;

               return CountBestanden;
           }
           catch (UnauthorizedAccessException) { count++; }
           return scanFiles();
           }

Maar eht probleem is als ik grote mappen zoals C: scant forzed mijn program dus kan het window niet meer verslepen en knop button blijft ingeklikt. Maar nadat hij gedaan is is die freeze weg is dit normaal ?
 
Dit is normaal voor alles wat je doet op de UI thread wat lang duurt.
Je kunt hiervoor threading/tasks/async gebruiken maar dat ik neem ik aan niet het doel van je (ik neem aan) oefening.


Als je in je code een exception vangt, en weer scanfiles aanroept heb je een loop die constant door blijft gaan, en zal je programma ook onbruikbaar maken. Hier is wat ik bedoelde met 0 returnen, maar dan weet je niet of er 0 bestanden waren geteld of dat er een fout was.
 
ja de bedoeling is dus Dat ik in een textbox het pad zet bv C:\ of een andere map
dan moet mijn programma uitrekenen hoeveel Bestanden en mappen er in die map staan ook met submappen en files bijgerekend hoeveel mb er in die map staat
en hoeveel onleesbare mappen en bestanden en die onleesbare bestanden en mappen vraag ik uds op door die exception te counten.

Maar het probleem is bv map C scannen dan blijft hij vastlopen msch idd een oneindige loop. en die listbox waar de path van alle bestanden staan wou ik graag met een thread oplossen maar weet niet echt hoe threads werken dusja. Dus ik zit een beetje vast hier. Het programma werkt dus maar vanaf grote mappen met onleesbare mappen loopt hij vast en mijn listbox waar alle paths van mijn mappen en bestanden staan moeten ook nog gemaakt worden.

Het enige probleem is hoe kan ik die exception oplossen en hoe kan ik die listbox intregreren
 
In plaats van C te scannen, maak je zelf een map en stop daar van alles wat in.
Je weet dan dat deze klein is en niet lang loopt, je weet hoeveel mappen en bestanden er in zitten en hoeveel ruimte deze in beslag nemen.

Als dit je uitgangspunt is het een stuk makkelijker om dit alvast werkend te krijgen en te controleren (zonder threading).

Als dan alles werkt kun je dingen er aan toevoegen zoals het op de achtergrond uitvoeren.

Het toevoegen aan een listbox kun je eenvoudig doen voordat je de bestanden.Length returned. Je hebt daar een bestanden array en daar loop je met een foreach zo doorheen om de naam de pakken de deze aan de listbox toe te voegen.
 
Ja met die foreach ik heb hem dus ook in mijn int methode gestopt maar dit lukt blijkbaar neit omdat ik geen string kan returnen ?
deze code staat ook in een klasse en ik moet die dus kunnen opvragen in mainwindow

public class DirectoryCalculator
{
public string pad;
public int count = 0;


public int scanFiles()
{
int CountBestanden;
try
{
DirectoryInfo dir = new DirectoryInfo(pad);



FileInfo[] bestanden = dir.GetFiles("*.*", SearchOption.AllDirectories);
foreach (FileInfo test in bestanden)
{

}
CountBestanden = bestanden.Length;

return CountBestanden;
}
catch (UnauthorizedAccessException) { count++; }
return scanFiles();
}

Hoe kan ik dit oplossen ?
 
Je kunt hetzelfde doen als je bij count doet, een lijst met strings maken en de bestandsnamen daar aan toevoegen.


[CPP]public List<string> Filenames = new List<string>();

filenames.Add(...[/CPP]

later kun je hierdoor gaan met een foreach en aan je listbox toevoegen.

(inplaats van string kun je ook een list met fileinfo's maken zodat je meer info hebt in de main window)
 
Omdat ik niet de hele thread heb meegekregen: Als het vanuit 1 directory omlaag is kun je zoiets doen:

Code:
        private void allfiles(string path)
        {
            int filesfound = 0;
            int dirsfound = 0;
            List<string> DL = new List<string>();
            object sync = new Object();

            try
            {
                DirectoryInfo di = new DirectoryInfo(path);
                DirectoryInfo[] DI = di.GetDirectories("*.*", SearchOption.AllDirectories);
                dirsfound = DI.Length;

                Parallel.ForEach(DI, curdir =>
                {
                    List<string> temp = new List<string>();
                    DirectoryInfo PerDir = new DirectoryInfo(curdir.FullName);
                    FileInfo[] bestanden = PerDir.GetFiles();
                    foreach (FileInfo fi in bestanden)
                    {
                        temp.Add(fi.Name);
                    }
                    lock (sync) { DL.AddRange(temp); filesfound = filesfound + temp.Count; }
                });
            }
            finally
            {
                listBox1.Items.AddRange(DL.ToArray());
                MessageBox.Show(@"dirs: " + dirsfound.ToString() + "  files found: " + filesfound.ToString());
            }
        }

stopt alle filenames van de opgegeven hoofddirectory en subdirectories in een listbox en toont een messagebox met het aantal gevonden dirs en files. De variable names zijn wat tacky etc, maar bedoel je zoiets?

*edit*: framework 4.5 met "using system.threading.tasks"
 
Laatst bewerkt:
wampier dit is niet mogelijk omdat die code in een lib klasse zit en ik daar geen listbox kan opvragen w8 i kgeef je eens mijn volledig code die ik nu momenteel gebruik
Die werkt maar als ik in een map scan waar er een exception in zit blijft hij door lussen.

Ik maak gebruik van een klasse omdat ik die code later ook nog voor een ander project zou willen gebruiken

mainwindow
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PE2.Events.Directorycalc.app
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Lib.DirectoryCalculator dir = new Lib.DirectoryCalculator();
        
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btNScan_Click(object sender, RoutedEventArgs e)
        {
           dir.pad = TbLocatie.Text;
           // DirectoryInfo di = new DirectoryInfo(dir.pad);
           lblBestanden.Content = dir.scanFiles();
           lblMappen.Content = dir.scanFolder();
           lblOnleesbareBestanden.Content = dir.count;

           


        }

        private void btnBladeren_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog fo = new System.Windows.Forms.FolderBrowserDialog();
            fo.SelectedPath = @"C:\Users\Alexander\Desktop\test";
            if (fo.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
               
                TbLocatie.Text = fo.SelectedPath;
                Properties.Settings.Default.Save();

            }
         
        }
    }
}

klasse
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PE2.Events.Directorycalc.Lib
{

   public class DirectoryCalculator
    {
       public string pad;
       public int count = 0;
    
       
       public int scanFiles()
       {
           int CountBestanden;
           try
           {
               DirectoryInfo dir = new DirectoryInfo(pad);



               FileInfo[] bestanden = dir.GetFiles("*.*", SearchOption.AllDirectories);
               foreach (FileInfo test in bestanden)
               {
                 
               }
               CountBestanden = bestanden.Length;

               return CountBestanden;
           }
           catch (UnauthorizedAccessException) { count++; }
           return scanFiles();
           }
     
   
       public int scanFolder()
       {
           
           DirectoryInfo dirM = new DirectoryInfo(pad);
           DirectoryInfo[] mappen = dirM.GetDirectories("*.*", SearchOption.AllDirectories);
           int Countmappen = mappen.Length;
           return Countmappen;
           
       }
       
    }
}
 
Ik snap het punt niet? Het feit dat je een aparte klasse hebt betekend dat je niet direct door kunt geven, maar veranderd aan de code zelf niets. Hoogstens de laatste stap.

geeft een list byref mee aan je object, of bouw een ienumerable in je class, of extend je class vanaf het list object, of neem een public list object in je class op, of ... 1000 mogelijkheden om de list uit mijn code uiteindelijk in je listbox te krijgen terwijl het in een andere class zit
 
ja kijk ik heb een try en een catch in die catch staat er een count die mijn fouten optelt ik zou ergens meoten gebruik maken voor een foreach voor alle gevonden mappen en bestanden in een lsitbox te stoppen maar omdat ik gebruik maak van een catch kan ik geen finally gebruiken. MAar als hij die catch oproept dan loopt mijn programma vast en blijft hij lussen ofzo ookal heb ik geen lus erin staan momenteel

Met die code dat je in mijn vorig bericht zag werkt maar gedeeltelijk dus ik zoek achter een oplossing.

ik zou dus graag een programma willen dat ik kan zien hoeveel mappen hoeveel bestanden hoeveel onleesbare mappen en hoeveel onleesbare bestanden er zijn. In mijn listbox komt er dan een lijst met het path van elk bestand. Die cath dient dus eindelijk voor het aantal onleesbare mappen en bestanden te counten. Ik heb een klasse directory lib gemaakt voor als ik die code nog in een ander prokect zou willen gebruiken later.
Het enige probleem is dat ik niet zo goed weet hoe events werken en hoe ik die onleesbare mappen en bestanden kan opvragen en die listbox.
Want als ik een map neem met onleesbare mappen en bestanden zoals C/ of system32 ofzo dan frozed mijn program en ik zou dit graag willen oplossen maar weet niet hoe. Kan er iemand mij hier mee helpen A.U.B
 
Laatst bewerkt:
waarom kun je geen finally gebruiken? werkt prima hoor. Ik zou eerst een lijst met dirs bouwen en dan files doorlopen. Als ik zo nog wat tijd heb kan ik wel eens een robustere versie proberen te geven
 
het probleem met die finally is dat ik een map scan zoals C dat mijn programma crached door de acces exception en als ik finally gebruik kan ik toch geen fouten opvangen ? want die fouten moeten opgeteld worden en zo bekom ik onleesbare bestanden
 
Ik heb even wat getest:
Scan geeft een result class terug met de bestanden en een aantal niet beschikbare folders.

Code:
public class DirScanner
{
	private List<FileInfo> _files;
	private int _restrictedCount;

	public DirScanner()
	{
		_restrictedCount = 0;
		_files = new List<FileInfo>();
	}

	public string Path { get; set; }
	public ScanResult Scan()
	{
		_restrictedCount = 0;
		_files.Clear();

		var mainDirectory = new DirectoryInfo(Path);

		if (!mainDirectory.Exists)
		{
			throw new ArgumentException("directory path provided is not accessable or does not exsist");
		}

		Scan(mainDirectory);

		return new ScanResult(_files, _restrictedCount);
	}

	private void Scan(DirectoryInfo directory)
	{
		try
		{
			var files = directory.GetFiles();
			_files.AddRange(files);
		}
		catch
		{
			_restrictedCount++;
			return;
		}

		var dirs = directory.GetDirectories();

		foreach (var dir in dirs)
		{
			Scan(dir);
		}
	}
}

Code:
public class ScanResult
{
	public List<FileInfo> Files { get; private set; }
	public int RestrictedFolderCount { get; private set; }

	public ScanResult(List<FileInfo> files, int restrictedFolderCount)
	{
		Files = files;
		RestrictedFolderCount = restrictedFolderCount;
	}
}


Gebruik + theaded:

Code:
    public partial class MainWindow : Window
    {
        private readonly DirScanner _scanner;

        public MainWindow()
        {
            InitializeComponent();
            _scanner = new DirScanner();
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            //set view and init scanner
            lstFiles.Items.Clear(); //listbox
            txtStatus.Text = "Scanning..."; //status textblock

            _scanner.Path = txtDirectory.Text; //textbox

            //start scan task
            var scanTask = new Task(ScanStuff);
            scanTask.Start();
        }

        private void ScanStuff()
        {
            ScanResult result;

            try
            {
                result = _scanner.Scan();
            }
            catch (Exception ex)
            {
                SetStatus(ex.Message);
                return;
            }

            foreach (var file in result.Files)
            {
                AddToList(file.Name);
            }
            
            SetStatus(string.Format("File Count: {0} | Restricted Folders: {1}", result.Files.Count, result.RestrictedFolderCount));
        }

        private void AddToList(string item)
        {
            //invoke due to threading
            this.Dispatcher.Invoke(() => { lstFiles.Items.Add(item); });
        }

        private void SetStatus(string message)
        {
            //invoke due to threading
            this.Dispatcher.Invoke(() => { txtStatus.Text = message; });
        }
    }


Ik heb het een paar keer getest en werkt, mag je zelf aanpassen zoals je wilt en meer testen :P
 
inderdaad dit is echt perfecte code eindelijk iets dat niet frozed word als er onleesbare mappen in zitten.
Maar in die listbox komen alleen de bestandsnamen ik zou eindelijk de plaats willen hebben zoals C:\program files\test\word.doc
ik heb al vanalles gedaan dus filename.Fullname ofwel heb ik net als jou enkel de bestandsnaam ofwel enkel de hoofdmap zoals C:\ maar geen volledig path.

En waar in die code kan ik nog dingen toevoegen bv hoeveel mappen er in de map test staan bv.
 
Het is mij ook nog niet om het vast te laten lopen. Hoewel mijn hele c:\ schijf wel een seconde of 10 duurt om te doorlopen ;)

*edit* ik krijg wel de volle directory met fullname in mijn code?
 
Laatst bewerkt:
bloodshed kan het zijn dat mijn code voor filesize niet meer werkt in jou code


klasse voor sizeconvertie
Code:
    public class convertor
    {
        public string ByteSize(double bytes)
        {
            string[] Suffix = { "KB", "MB", "GB", "TB" };
            int index = 0;
            do { bytes /= 1024; index++; }
            while (bytes >= 1024);
            return String.Format("{0:0.0} {1}", bytes, Suffix[index]);
        }

en de klasse van jou met mijn sizeconvertie

Code:
    public class DirScanner
    {
        private List<FileInfo> _files;
        private List<DirectoryInfo> _mappen;
        private int _restrictedCount;

        public DirScanner()
        {
            _restrictedCount = 0;
            _mappen = new List<DirectoryInfo>();
            _files = new List<FileInfo>();
        }

        public string Path { get; set; }
        public ScanResult Scan()
        {
            _restrictedCount = 0;
            _files.Clear();
            _mappen.Clear();

            var mainDirectory = new DirectoryInfo(Path);

            if (!mainDirectory.Exists)
            {
                throw new ArgumentException("directory path provided is not accessable or does not exsist");
            }

            Scan(mainDirectory);

            return new ScanResult( _files,_mappen, _restrictedCount);
        }

        private void Scan(DirectoryInfo directory)
        {
            try
            {
                var files = directory.GetFiles();
                _files.AddRange(files);
                var mappen = directory.GetDirectories();
                _mappen.AddRange(mappen);
            }
            catch
            {
                _restrictedCount++;
                return;
            }

            var dirs = directory.GetDirectories();

            foreach (var dir in dirs)
            {
                Scan(dir);
            }
        }
        private void size(FileInfo filesize)
        {
            convertor conv = new convertor();
            long size = Convert.ToInt64(filesize.Length);
            
            
            for (int i = 0; i < filesize.Length; i++)
            {


               
                size += filesize[i].Length / 1024;
                string sizecontent = conv.ByteSize(size); //de string word dan in mainwindow verwezen naar de label size

                //size;


            }
        }
    }
}
 
Als je niets hebt gewijzigd aan de method die de size string maakt en de input is hetzelfde zie ik geen reden waarom er iets niet meer zou werken.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan