0

lets say I have a folder with some files and I would like to copy them all in every random seconds (lets say random between 1sec and 1 hour -> is this possible?) in a random order. I know with File.Copy("from", "to"); you can copy files. But I need this random stuff. Any ideas?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
silla
  • 1,257
  • 4
  • 15
  • 32
  • Do you mean copy part of the file in a random order as well, or should you copy the file as a whole, just at a random time? – Patrick Sep 10 '12 at 22:04
  • I know we are not suppose to question questions but could you share why you want this? – paparazzo Sep 10 '12 at 22:05
  • @Patrick copy all of the files in the folder every x seconds. Lets say in the folder are file A,B,C,D so copy ALL of them in second x BUT randomly, so not always A then B then C then D it should be randomly. – silla Sep 10 '12 at 22:07
  • @Blam To test another application – silla Sep 10 '12 at 22:08
  • Do you know how many files there are at each time t? –  Sep 10 '12 at 22:10
  • @diophantine I dont. Would like to copy all of the files that are in the folder – silla Sep 10 '12 at 22:13

6 Answers6

4

Read the files into a list and shuffle using this

Randomize a List<T>

Then in the copy loop just sleep a random milliseconds from 1000 to 3600000

    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo("dirctory path");

    List<System.IO.FileInfo> files = di.GetFiles().ToList();

    di = null;  // at this point I don't think you need to hold on to di

    // the static Directory will return string file names

    // randomize files using the code in the link 
    Random random = new Random();
    foreach (System.IO.FileInfo fi in files)
    {
        Thread.Sleep(random.Next(1000, 3600000));
        // should probaly test the fi is still valid
        fi.CopyTo("desitination");
    }
Community
  • 1
  • 1
paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • 1
    Rather than reading the files themselves into FileStreams and hanging onto them, I would use Directory.GetFiles() to retrieve FileInfo objects representing the file metadata, and store those. This way, no handles to the actual files have to be retained which can gum up the works elsewhere. – KeithS Sep 10 '12 at 22:21
  • I agree. And that is what I meant but not what my words said. GetFiles() return name plus path no a FileInfo. But agree with your point. – paparazzo Sep 10 '12 at 22:24
  • @KiethS I think need to use DirectoryInfo to get FileInfo. I am testing it out now. – paparazzo Sep 10 '12 at 22:29
  • another thing is it's execution mean is N*30 min, not an hour. to make it span over an hour, the high limit should be 3600000/files.Count. The low limit for random is also affected like this. It will never complete faster than N seconds. – aiodintsov Sep 11 '12 at 20:00
  • @aiodintsov Please refer to the question. "random between 1 sec and 1 hour" It did get marked as the correct answer. You really think they want the the total for all files to vary between 1 minute and 1 hour for all files when he does not even know the file count? – paparazzo Sep 11 '12 at 20:10
1

This should work:

Random random = new Random();

int seconds = random.Next(3600) + 1;
List<FileInfo> files = new DirectoryInfo(Environment.CurrentDirectory).GetFiles().ToList();

Timer timer = new Timer() { Interval = seconds * 1000, AutoReset = true };
timer.Elapsed += (s, e) =>
    {
        files = files.OrderBy(f => random.NextDouble()).ToList();
        foreach(FileInfo file in files)
        {
            try { file.CopyTo("SomeDestination"); }
            catch { Console.WriteLine("Error copying file " + file); }
        }
    };
timer.Start();
itsme86
  • 19,266
  • 4
  • 41
  • 57
1

try this

        Timer t = new Timer();
        t.Interval = 1;
        t.Enabled = true;
        t.Tick += (s, o) =>
            {
                // interval between 1000ms(1s) & 1H
                t.Interval =1000*( new Random().Next(3600));
                string[] still_files ;
                do
                {
                    still_files = Directory.GetFiles(@"c:\source").Select(X => Path.GetFileName(X))
                    .Except(Directory.GetFiles(@"c:\destination").Select(X => Path.GetFileName(X)))
                    .ToArray();

                File.Copy(Path.Combine(@"c:\source", still_files[new Random().Next(still_files.Count()) - 1]), @"c:\destination");
                } while (still_files.Count> 0);
            };
S3ddi9
  • 2,121
  • 2
  • 20
  • 34
  • This doesn't address copying a random file at all. – itsme86 Sep 10 '12 at 22:22
  • he want to copy them **all**, but in random time interval, read the question again, is that right @silla – S3ddi9 Sep 10 '12 at 22:23
  • Maybe you should read the question again. He wants to copy all of the files, yes, but in a random order. – itsme86 Sep 10 '12 at 22:27
  • I take all in a random order not to mean each file once but a random order. This will just keep copying. And a file can repeat before a file is even copied once. If that is what the OP wants then great. But not how I read it. – paparazzo Sep 10 '12 at 22:46
1

It is possible. The most naive implementation could be like this:

    static void Main(string[] args)
    {
        var files = Directory.GetFiles(@"c:\temp");
        var dest = @"c:\temp2";
        var rnd = new Random();
        int maxDelay = 60; // one minute

        var schedule = files.Select(f => new {FilePath = f, Delay = rnd.Next(maxDelay)}).ToList();
        schedule.Sort( (a,b) => a.Delay-b.Delay );

        var startTime = DateTime.Now;

        foreach (var s in schedule)
        {
            int curDelay = (int) (DateTime.Now - startTime).TotalSeconds;

            if (s.Delay <= curDelay) File.Copy(s.FilePath, Path.Combine(dest, Path.GetFileName(s.FilePath)));
            else {
                Thread.Sleep((s.Delay-curDelay)*1000);
                File.Copy(s.FilePath, Path.Combine(dest, Path.GetFileName(s.FilePath)));
            }
        }
    }

so - let's create a list of files. then assign random delays. then sort them by delay value. then go through the list copying the files if it's time has come or sleeping until the time of the next copy time.

after the loop is done all files are copied each at about it's delay time.

aiodintsov
  • 2,545
  • 15
  • 17
  • curDelay is cumulative not between. And if a file does not meet the delay then it is not copied at all. It meerly sleeps one second and goes to the next. – paparazzo Sep 10 '12 at 23:09
  • and if the delay is met then there is zero delay on the next file – paparazzo Sep 10 '12 at 23:12
  • curDelay is not "cumulative", it's absolute. as file delays are. there are no zero delays. it will copy everything those delays already come, and then will sleep as much as needed for the next copy. well, there is one flow at this point - it should reattempt file copy. updated. – aiodintsov Sep 11 '12 at 19:55
0

Get all your filenames into an array, pick a random string from your array, use this to get the file.

Use a timer with a random integer. If you don't know how to use random numbers then it's simply Random rand = new Random() with rand.Next(10), this would return a random integer between 0 and 9.

Joe Shanahan
  • 816
  • 5
  • 21
0

Look up the System.Random class. You can use that to generate integers between 1 and 3600, 3600 being the number of seconds in a hour.

To randomize the filenames, put them in an array and then sort the array by r.Next() where r is an instance you previously created of System.Random.

Ann L.
  • 13,760
  • 5
  • 35
  • 66