Search code examples
c#filestream

File.OpenRead() Directories , Sub Directories , Files, and then Write Folders and files to another directory


I am looking to read folders and files from a directory structure like so.. e.g

C:\RootFolder
            SubFolder1
               SubFolder2
                   File1
                   File2
                         SubFolder3
                                 File3
 Files....
 Files....

I would like to read both, files and folders and write to another directory I cant use copy , because the directory I want to write to is remote and not local.

I read the files here.... Id love to be able to read folders and files and write both to another directory.

 public static IEnumerable<FileInfo> GetFiles(string dir)
        {
            return Directory.EnumerateFiles(dir, "*", SearchOption.AllDirectories)
                .Select(path =>
                {                    
                    var stream = File.OpenRead(path);
                    return new FileInfo(Path.GetFileName(path), stream);
                })
                .DisposeEach(c => c.Content);
        }

this function writes files to a remote sftp site.

 public Task Write(IEnumerable<FileInfo> files)
        {
            return Task.Run(() =>
            {
                using (var sftp = new SftpClient(this.sshInfo))
                {
                    sftp.Connect();
                    sftp.ChangeDirectory(this.remoteDirectory);

                    foreach (var file in files)
                    {
                      sftp.UploadFile(file.Content, file.RelativePath);
                    }
                }
            });
        }

In this function I write the read files from the above function.

    private async static Task SendBatch(Config config, Batch batch, IRemoteFileWriter writer)
    {
        var sendingDir = GetClientSendingDirectory(config, batch.ClientName);
        Directory.CreateDirectory(Path.GetDirectoryName(sendingDir));
        Directory.Move(batch.LocalDirectory, sendingDir);
        Directory.CreateDirectory(batch.LocalDirectory);
        //Use RemoteFileWriter...
        var files = GetFiles(sendingDir);

        await writer.Write(files).ContinueWith(t =>
        {
            if(t.IsCompleted)
            {
                var zipArchivePath = GetArchiveDirectory(config, batch);
                ZipFile.CreateFromDirectory(
                    sendingDir,
                    zipArchivePath + " " +
                    DateTime.Now.ToString("yyyy-MM-dd hh mm ss.Zip")
                    );
            }
        });



    }

Thank you!


Solution

  • You are getting UnauthorizedAccessException: Access to the path 'C:\temp' is denied. because you can't open a stream from a folder as it doesn't contain bytes.

    From what I can understand you are looking to copy the files from one folder to another.

    This answer seems to cover what you are doing. https://stackoverflow.com/a/3822913/3634581

    Once you have copied the directories you can then create the zip file.

    If you don't need to copy the files and just create the Zip I would recommend that since it will reduce the disk IO and speed up the process.

    ZipArchive (https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx) can be used to create a zip file straight to a stream.