简体   繁体   中英

FileInfo Error for getting length size

    private long yy=0;

    private void CopyAll(DirectoryInfo source,DirectoryInfo target )
    {

        if (Directory.Exists(target.FullName) == false)
        {
            try
            {
                Directory.CreateDirectory(target.FullName);
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }

        }
        foreach (FileInfo fi in source.GetFiles())
        {
                yy += fi.Length;
                backgroundWorker1.ReportProgress((int)yy / 1024);

        }
        foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
        {

                DirectoryInfo nextTargetSubDir =
                    target.CreateSubdirectory(diSourceSubDir.Name);
                CopyAll(diSourceSubDir, nextTargetSubDir);               
        }

The result i get when i do this is a negative number and the wrong value, has this been answered before and does anyone know what am doing wrong?

As asked by other people. what is "yy" ? is it an integer? a long? a byte? a single? a double? a string? Nobody knows. yy is surrounded in mystery. I will presume yy is a "long" as for a total file size this is probably the safest way (although still prone to issues). I will also overlook your variable name mis-match to help with your question.

Light reading material before we head off: https://en.wikipedia.org/wiki/Integer_overflow

yy i am presuming is your total file size for the source directories files. as yy reaches its max value as specified by [datatype].MaxValue in a signed value as it goes over it will set off with what's left from [datatype].MinValue. break on each iteration, where yy gets added to and add a watch to "yy". You will see its value slowly (or quickly, depending on the size of the files in the directory) reach [datatype].MaxValue. when this is reached and continually added to it will return to MinValue.

For some interactive learning try out this piece of code:

        long val = long.MaxValue;
        val += 1;

inspect val, You will see it's -9223372036854775808. (See previous light learning material)

Your question has to be "what am I achieving here". Do you HAVE to know the total sizes of all files or can you achieve it differently. A common way to achieve extra-large size values is to keep a reference to each unit in its own data store. by unit i mean unit, tens, hundreds, thousands, etc etc etc and add your single.Length to this. You will have to write this yourself.

You can use a float for extra large numbers but it depends entirely on how accurate you need your reading to be. (floats lose precision as the number gets bigger)

Edit: also another point to consider after looking over your code again. you are casting yy to an int in your report progress. if yy is long and cast to an int when yy is bigger than int.MaxValue, you will see the same issue. why are you casting yy to an int? why not just divide by 1024 on yy directly and then cast to int (still presuming yy is a long)

(int)(yy / 1024)

Edit 2: Following your elaborated code you are recursing through folders you pretty much absolutely have hit MaxValue on your yy value.

Edit 3: Why do you care about total size of all files when you are writing what appears to be a "Copy" method to copy an entire directory structure across. (Notice you make directories in the destination directory but do not copy any files over so it appears to be a directory structure copy and not data) If you want to do some kind of "is there enough space in the destination to do this copy" you should calculate space before doing anything in the destination location.

Good luck!

Directory.GetFiles() will give you a list of Strings. you cannot convert it directly as FileInfo that's the problem here. FileInfo.Length will return size of file in bytes , so range of integer is not enough to hold the value if the file size is large. so check the datatype of yy

So i suggest you to do something like the following:

  foreach (string F in Directory.GetFiles("D:\YourDirectory"))
     {
         FileInfo tempFileInfo = new FileInfo(F);
         yy += tempFileInfo.Length;
         backgroundWorker1.ReportProgress((int)yy / 1024);
     } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM