Move Directory to Google Bucket - c#

How can we move entire folder(within folder have many sub directory too) to Bucket of google cloud? Can anyone help on this.

Use -r flag in gsutil copy command.
From gsutil documentation:
If you want to copy an entire directory tree you need to use the -r option. For example, to upload the directory tree "dir":
gsutil cp -r mydir gs://my-bucket

The Cloud Storage Client for C # library does not support uploading folders, you must create a function (sync / asynchronous) that gets all the files/subfolders inside your folder and uploads each file.
I found a folder iterator code in this Microsoft Link In my code example I added the GCS library to upload the files, it is not necessary to create a folder structure.
For example
// GCS dependencies
using Google.Apis.Storage.v1;
using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using Storage;
// GCS dependencies
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
static void WalkDirectoryTree(System.IO.DirectoryInfo root)
{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
// initialize the GCS client library
var storage = StorageClient.Create();
// use this variable to define the upload bucket, please use your bucket name
var bucketName= Myawesomebucket
try
{
files = root.GetFiles("*.*");
}
catch (UnauthorizedAccessException e)
{
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
// If we
// want to open, delete or modify the file, then
// a try-catch block is required here to handle the case
// where the file has been deleted since the call to TraverseTree().
Console.WriteLine(fi.FullName);
// this section is used to upload files to GCS
// the object name includ folder/subfolder structure
objectName = objectName ?? Path.GetFileName(fi.FullPath);
// upload the object to the bucket
storage.UploadObject(bucketName, objectName, null, f);
Console.WriteLine($"Uploaded {objectName}.");
}
// Now find all the subdirectories under this directory.
subDirs = root.GetDirectories();
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo);
}
}
}

Related

How to handle a case when the hard disk drive letter is not the same when saved it to a text file?

in the constructor :
SaveLoadFiles.LoadFile(textBoxRadarPath, "radarpath.txt");
SaveLoadFiles.LoadFile(textBoxSatellitePath, "satellitepath.txt");
if (textBoxRadarPath.Text != "" || textBoxSatellitePath.Text != "")
{
if(!Directory.Exists(textBoxRadarPath.Text))
{
Directory.CreateDirectory(textBoxRadarPath.Text);
}
if (!Directory.Exists(textBoxSatellitePath.Text))
{
Directory.CreateDirectory(textBoxSatellitePath.Text);
}
btnStart.Enabled = true;
}
else
{
btnStart.Enabled = false;
}
the SaveLoadFiles class
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Weather
{
public class SaveLoadFiles
{
public static void SaveFile(string contentToSave, string fileName)
{
string applicationPath = Path.GetFullPath(System.AppDomain.CurrentDomain.BaseDirectory); // the directory that your program is installed in
string saveFilePath = Path.Combine(applicationPath, fileName);
File.WriteAllText(saveFilePath, contentToSave);
}
public static void LoadFile(TextBox loadTo, string fileName)
{
string applicationPath = Path.GetFullPath(System.AppDomain.CurrentDomain.BaseDirectory); // the directory that your program is installed in
string saveFilePath = Path.Combine(applicationPath, fileName); // add a file name to this path. This is your full file path.
if (File.Exists(saveFilePath))
{
loadTo.Text = File.ReadAllText(saveFilePath);
}
}
}
}
when i used the application before and backed it up on my usb flash drive the second hard drive letter was D i had two hard disks : C and D and the project and the folders were on drive D.
now i backed up the project including the saved files but now my hard disks letters are C and E there is no D
but in the constructor when it's reading the text files the folders in the text files are D:....etc
but it should be E:
I'm checking if the folder exist or not and then if not creating it but it's trying to create the folder on drive D and D is not existing.
You are reading contents of a data file that has a file path that no longer exists.
The solution is to edit those data files: "radarpath.txt" and "satellitepath.txt" to have the proper path.
An application would normally provide a UI for selecting the folder to use, rather than saving a hardcoded path in a datafile. What you could do is use FileDialog to prompt the user for the directories to use if they don't exist.

Find the path in dll

I have a dll file as a resource in my project. Now I would like to access the directory folder in the dll.
E.g. Image dll (In Image.dll -> \Image\PresetFolder)
I would like to Directory.Getdirectories() folder path in the Image.dll
How could I can achieve this in c#???
At last, my friend provide me the answer, you have to load the dll first before get the directory path with code
private string[] GetAllResourcePath()
{
Assembly assembly = Assembly.Load("ImageDLL");
string resName = "ImageDLL.g.resources";
using (var stream = assembly.GetManifestResourceStream(resName))
{
using(var reader = new ResourceReader(stream))
{
return reader.Cast<DictionaryEntry>().Select(x => (string)x.Key).ToArray();
}
}
}
From this func, it will return all the resource directory path, and you can just filter out by using .Where() linq to get the directory you want.

Add recursive command to set sub directory permissions in C#

I would like to add a recursive command to this script that allows it to loop through a current direcotries sub directory/files and set the permissions on the subfolders/files to whatever I would like. Here is what I have so far which allows for the permissions to be changed on the first set of subdirectories. Obviously, I can add the samecode in to keep diving down through the folder structure, but not every root folder will have the same amount of sub folders within it. I want to add the recursive command to loop through all subdirectories and when there are no more, move on to the next root folder.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Management.Instrumentation;
namespace ApplyPermissions
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void selectDirectoryBtn_Click(object sender, EventArgs e)
{
FolderBrowserDialog myFolderBrowserDialog = new FolderBrowserDialog();
myFolderBrowserDialog.ShowDialog();
selectedDirBox.Text = myFolderBrowserDialog.SelectedPath.ToString();
try
{
DirectoryInfo myDirectoryInfo = new DirectoryInfo(selectedDirBox.Text);
foreach (DirectoryInfo currentDir in myDirectoryInfo.GetDirectories())
{
toolStripStatusLabel1.Text = currentDir.Name;
DirectorySecurity DirSecurity = currentDir.GetAccessControl();
DirSecurity.AddAccessRule(new FileSystemAccessRule(“Whatever permissions group I choose”, FileSystemRights.CreateFiles, AccessControlType.Allow));
currentDir.SetAccessControl(DirSecurity);
// Step thru each file within current Directory and assign access
foreach (FileInfo currentFile in currentDir.GetFiles())
{
FileSecurity fileSecurity = currentFile.GetAccessControl();
fileSecurity.AddAccessRule(new FileSystemAccessRule("Whatever permissions group I choose", FileSystemRights.FullControl, AccessControlType.Allow));
currentFile.SetAccessControl(fileSecurity);
}
foreach (DirectoryInfo subDir in currentDir.GetDirectories ())
{
toolStripStatusLabel1.Text = currentDir.Name + "/" + subDir.Name;
DirectorySecurity allsubDirSecurity = subDir.GetAccessControl();
allsubDirSecurity.AddAccessRule(new FileSystemAccessRule("Whatever permissions group I choose ", FileSystemRights.FullControl, AccessControlType.Allow));
subDir.SetAccessControl(allsubDirSecurity);
// Step thru each file within current SubDirectory and assign access
foreach (FileInfo currentFile in subDir.GetFiles())
{
FileSecurity fileSecurity = currentFile.GetAccessControl();
fileSecurity.AddAccessRule(new FileSystemAccessRule("Whatever permissions group I choose", FileSystemRights.FullControl, AccessControlType.Allow));
currentFile.SetAccessControl(fileSecurity);
}
}
}
labelFinished.Text = "Completed Successfully";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "/////////////////" + ex.StackTrace);
}
}
}
}
First, if your target framework is 4.0, recommend that you use the Directory.EnumerateFiles method (you can also find 3rd code that does the same thing.)
Assuming this is a no-go, you can simplify your recursive processing by using the yield keyword, e.g. make a traverse method based on yield -- I'm showing this with a filter function to since it would often be useful in directory traversal ad should give you ideas.
static IEnumerable<string> traverse(string path, Func<string, bool> filter)
{
foreach (string f in Directory.GetFiles(path).Where(filter))
{
yield return f;
}
foreach (string d in Directory.GetDirectories(path))
{
foreach (string f in traverse(d, filter))
{
yield return f;
}
}
}
Then you use traversal() this way
var files = traverse(PATH, WHERE);
foreach (string f in files) { DoWhatever; }
You will have a more easily reusable directory traversal at your fingertips. I know that I am not yielding directories in the snippet above, but if I wanted to process both files and directory, I would base this on the DirectoryInfo.GetFileSystemInfos method instead.
I forget when the yield feature was added, but it has been available for quite a while.

Rename a file in C# (NET 2.0) without moving it or using DOS / Visual Basic commands

I have not found yet a file-rename-function in .NET for C#, so I'm a bit confused how I would rename a file. I use the command prompt with Process.Start, but this isn't really professional and a black DOS window is popping up each time. Yes, I know there is something in the Visual Basic namespace, but this is not my intention to add the "visual-basic.dll" to my project.
I found some examples which "move" the file to rename it. It is a quite painful method and a shoddy workaround for things. Such footwork I can program myself.
Every language has renaming commands, so I am stunned that C# hasn't or I haven't found out yet. What is the right command?
For large files and to rename on CD, this code works, but your project will be partly converted into Visual Basic (as I understand it, maybe it is not so):
//Add the Microsoft.VisualBasic.MyServices reference and namespace in a project;
//For directories:
private static bool RenameDirectory(string DirPath, string NewName)
{
try
{
FileSystemProxy FileSystem = new Microsoft.VisualBasic.Devices.Computer().FileSystem;
FileSystem.RenameDirectory(DirPath, NewName);
FileSystem = null;
return true;
}
catch {
return false;
} //Just shut up the error generator of Visual Studio
}
//For files:
private static bool RenameFile(string FilePath, string NewName)
{
try
{
FileSystemProxy FileSystem = new Microsoft.VisualBasic.Devices.Computer().FileSystem;
FileSystem.RenameFile(FilePath, NewName);
FileSystem = null;
return true;
}
catch {
return false;
} //Just shut up the error generator of Visual Studio
}
A rename is just a move and vice versa, see the MSDN : File.Move
In the OS the operations are the same for all intents an purposes. That's why in explorer a move on the same partition is near instantaneous - just adjusts the file name and logical location. To Rename a file in the same directory you Move it to a new File Name in the same directory.
using System;
using System.IO;
class Test
{
public static void Main()
{
string path = #"c:\temp\MyTest.txt";
string path2 = #"c:\temp2\MyTest.txt";
try
{
if (!File.Exists(path))
{
// This statement ensures that the file is created,
// but the handle is not kept.
using (FileStream fs = File.Create(path)) {}
}
// Ensure that the target does not exist.
if (File.Exists(path2))
File.Delete(path2);
// Move the file.
File.Move(path, path2);
Console.WriteLine("{0} was moved/renamed to {1}.", path, path2);
// See if the original exists now.
if (File.Exists(path))
{
Console.WriteLine("The original file still exists, which is unexpected.");
}
else
{
Console.WriteLine("The original file no longer exists, which is expected.");
}
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
}
}

Quickest way to use C# to programmatically search entire computer for several dozen unique filenames?

I am writing a program to do compatibility checking... Basically I am going to have a database that contains filenames, and version info for specific file.
This database will store hundreds of unique filenames, and these files could exist in many places on a clients computer.
I could probably do additional work and find out where each file is "suppose" to exist, but obviously that will sometimes be machine dependent, for example 32 bit system files might exist in program files, 64 bit could be either program files or program files (x86).
However, it is also possible that multiple versions of these files exist in different places on the computer, and could be stored in temp data directories like appdata.
So really what I would like to do is search the entire root drive, for all instances of these files, check the file version, and compare that against what is in the database.
Searching the entire root directory and all sub directories for 1 file is time consuming, let alone iterating through hundreds of unique filenames 1 at a time searching entire root.
Would it be easier to just return a list of all files on machine and location, write that to temp table, and then i can iterate through my list of files in sql which would be much quicker?
Dunno, but I would like this search to be fairly quick, not take 2 hours.... ;-)
I just tested this code against my C drive (SSD) with a few files. It found 291,935 files in 14.79 seconds. Now you just need to iterated over your collection of files and match by name - then check versions. The use of the Parallel For / Foreach loop would prove useful here.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var b = new BuildFileList();
var sw = new Stopwatch();
sw.Start();
var files = b.GetFiles();
sw.Stop();
Console.WriteLine("Found {0} files in {1} seconds", files.Count, sw.Elapsed.TotalSeconds);
Console.ReadLine();
}
}
public class BuildFileList
{
public List<FileInfo> GetFiles()
{
var di = new DirectoryInfo(#"C:\");
var directories = di.GetDirectories();
var files = new List<FileInfo>();
foreach (var directoryInfo in directories)
{
try
{
GetFilesFromDirectory(directoryInfo.FullName, files);
}
catch (Exception)
{
}
}
return files;
}
private void GetFilesFromDirectory(string directory, List<FileInfo> files)
{
var di = new DirectoryInfo(directory);
var fs = di.GetFiles("*.*", SearchOption.TopDirectoryOnly);
files.AddRange(fs);
var directories = di.GetDirectories();
foreach (var directoryInfo in directories)
{
try
{
GetFilesFromDirectory(directoryInfo.FullName, files);
}
catch (Exception)
{
}
}
}
}
}

Categories