I use a FileUploader control in my application. I want to save a file to a specified folder. If this folder does not exist, I want to first create it, and then save my file to this folder. If the folder already exists, then just save the file in it.
How can I do this?
Use System.IO.Directory.CreateDirectory.
According to the official ".NET" docs, you don't need to check if it exists first.
System.io > Directory > Directory.CreateDirectory
Any and all directories specified in path are created, unless they already exist or unless some part of path is invalid. If the directory already exists, this method does not create a new directory, but it returns a DirectoryInfo object for the existing directory.
— learn.microsoft.com/dotnet/api/
Use the below code as per How can I create a folder dynamically using the File upload server control?:
string subPath ="ImagesPath"; // Your code goes here
bool exists = System.IO.Directory.Exists(Server.MapPath(subPath));
if(!exists)
System.IO.Directory.CreateDirectory(Server.MapPath(subPath));
Just write this line:
System.IO.Directory.CreateDirectory("my folder");
If the folder does not exist yet, it will be created.
If the folder exists already, the line will be ignored.
Reference: Article about Directory.CreateDirectory at MSDN
Of course, you can also write using System.IO; at the top of the source file and then just write Directory.CreateDirectory("my folder"); every time you want to create a folder.
Directory.CreateDirectory explains how to try and to create the FilePath if it does not exist.
Directory.Exists explains how to check if a FilePath exists. However, you don't need this as CreateDirectory will check it for you.
You can create the path if it doesn't exist yet with a method like the following:
using System.IO;
private void CreateIfMissing(string path)
{
bool folderExists = Directory.Exists(Server.MapPath(path));
if (!folderExists)
Directory.CreateDirectory(Server.MapPath(path));
}
This method will create the folder if it does not exist and do nothing if it exists:
Directory.CreateDirectory(path);
You can use a try/catch clause and check to see if it exist:
try
{
if (!Directory.Exists(path))
{
// Try to create the directory.
DirectoryInfo di = Directory.CreateDirectory(path);
}
}
catch (IOException ioex)
{
Console.WriteLine(ioex.Message);
}
using System.IO
if (!Directory.Exists(yourDirectory))
Directory.CreateDirectory(yourDirectory);
if (!Directory.Exists(Path.GetDirectoryName(fileName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
}
The following code is the best line(s) of code I use that will create the directory if not present.
System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/temp/"));
If the directory already exists, this method does not create a new directory, but it returns a DirectoryInfo object for the existing directory. >
Create a new folder, given a parent folder's path:
string pathToNewFolder = System.IO.Path.Combine(parentFolderPath, "NewSubFolder");
DirectoryInfo directory = Directory.CreateDirectory(pathToNewFolder);
// Will create if does not already exist (otherwise will ignore)
path to new folder given
directory information variable so you can continue to manipulate it as you please.
Use this code if the folder is not presented under the image folder or other folders
string subPath = HttpContext.Current.Server.MapPath(#"~/Images/RequisitionBarCode/");
bool exists = System.IO.Directory.Exists(subPath);
if(!exists)
System.IO.Directory.CreateDirectory(subPath);
string path = HttpContext.Current.Server.MapPath(#"~/Images/RequisitionBarCode/" + OrderId + ".png");
Use the below code. I use this code for file copy and creating a new folder.
string fileToCopy = "filelocation\\file_name.txt";
String server = Environment.UserName;
string newLocation = "C:\\Users\\" + server + "\\Pictures\\Tenders\\file_name.txt";
string folderLocation = "C:\\Users\\" + server + "\\Pictures\\Tenders\\";
bool exists = System.IO.Directory.Exists(folderLocation);
if (!exists)
{
System.IO.Directory.CreateDirectory(folderLocation);
if (System.IO.File.Exists(fileToCopy))
{
MessageBox.Show("file copied");
System.IO.File.Copy(fileToCopy, newLocation, true);
}
else
{
MessageBox.Show("no such files");
}
}
A fancy way is to extend the FileUpload with the method you want.
Add this:
public static class FileUploadExtension
{
public static void SaveAs(this FileUpload, string destination, bool autoCreateDirectory) {
if (autoCreateDirectory)
{
var destinationDirectory = new DirectoryInfo(Path.GetDirectoryName(destination));
if (!destinationDirectory.Exists)
destinationDirectory.Create();
}
file.SaveAs(destination);
}
}
Then use it:
FileUpload file;
...
file.SaveAs(path,true);
string root = #"C:\Temp";
string subdir = #"C:\Temp\Mahesh";
// If directory does not exist, create it.
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
The CreateDirectory is also used to create a sub directory. All you have to do is to specify the path of the directory in which this subdirectory will be created in. The following code snippet creates a Mahesh subdirectory in C:\Temp directory.
// Create sub directory
if (!Directory.Exists(subdir))
{
Directory.CreateDirectory(subdir);
}
Derived/combined from multiple answers, implementing it for me was as easy as this:
public void Init()
{
String platypusDir = #"C:\platypus";
CreateDirectoryIfDoesNotExist(platypusDir);
}
private void CreateDirectoryIfDoesNotExist(string dirName)
{
System.IO.Directory.CreateDirectory(dirName);
}
Related
I have a directory with folders and files, and I want to move all the folders into another folder that's inside the directory.
I already can move all the files in the directory(Not including the files in the subfolders), but I am also trying to figure out how to move the subfolders.
string selectedDrive = comboBox1.SelectedItem.ToString();
string folderName = selectedDrive + #"\\Encrypted"; // Creates a directory under the selected drive.
System.IO.Directory.CreateDirectory(folderName);
string moveTo = (selectedDrive + #"\Encrypted");
String [] allFolders = Directory.GetDirectories(selectedDrive); //Should return folder
foreach (String Folder in allFolders)
{
if (!Directory.Exists(moveTo + Folder))
{
FileSystem.CopyDirectory(Folder, moveTo);
}
}
Instead, I have an error at this line FileSystem.CopyDirectory(Folder, moveTo);
saying the following: System.IO.IOException: 'Could not complete operation since source directory and target directory are the same.'
I have reworked your code to make it work in this way:
// source of copies, but notice the endslash, it's required
// if you use the string replace method below
string selectedDrive = #"E:\temp\";
string destFolderName = Path.Combine(selectedDrive, "Encrypted");
System.IO.Directory.CreateDirectory(destFolderName);
// All folders except the one just created
var allFolders = Directory.EnumerateDirectories(selectedDrive)
.Except(new[] { destFolderName });
// Loop over the sources
foreach (string source in allFolders)
{
// this line in framework 4.8,
string relative = source.Replace(selectedDrive, "");
// or this line if using NET Core 6
// string relative = Path.GetRelativePath(selectedDrive, source));
// Create the full destination name
string dest = Path.Combine(destFolderName, relative);
if (!Directory.Exists(dest))
{
FileSystem.CopyDirectory(source, dest);
}
}
Also noted now that you are using a root drive (F:) as source for the directories to copy. In this case you should consider that you have other folders not accessible or not copy-able. (For example the Recycle.bin folder). However you can easily add other exclusions to the array passed to the IEnumerable extension Except
....
.Except(new[] { destFolderName, "Recycle.bin" });
I am trying to locate a file on my computer so I can store my game's login data on that certain file. I have a string that contains the path.
public string path = "C:/Users/DevelopVR/Documents";
//DevelopVR is my username
Then I have this later on:
if (System.IO.File.Exists(path))
{
Debug.Log("Path exists on this computer");
}
else
{
Debug.LogWarning("Path does NOT exist on this computer");
}
I have also tried swapping out this:
else
{
Debug.LogWarning("Path does NOT exist on this computer");
}
With this:
else if (!System.IO.File.Exists(path))
{
Debug.LogWarning("Path does NOT exist on this computer");
}
But every time it logs the error. So I don't know what to do. It seems like other people are having the same problem. Thanks, If you have the answer.
Documents is a Directory, not a File, so instead of checking for File, check for Directory like:
if(File.Exists(path))
{
// This path is a file
ProcessFile(path);
}
else if(Directory.Exists(path))
{
// This path is a directory
ProcessDirectory(path);
}
Remember that if you want to search for a File, your path should have the file name and extension like:
public string path = #"C:/Users/DevelopVR/Documents/MyFile.txt";
"Documents" is not a real path, it's a convenience link to the 'special folder' that Windows provides.
From https://learn.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netcore-3.1
// Sample for the Environment.GetFolderPath method
using System;
class Sample
{
public static void Main()
{
Console.WriteLine();
Console.WriteLine("GetFolderPath: {0}", Environment.GetFolderPath(Environment.SpecialFolder.System));
}
}
/*
This example produces the following results:
GetFolderPath: C:\WINNT\System32
*/
static void SendMail()
{
String SystemErrors = DateTime.Now.ToString("d");
String filepath = #"C:\Windows\Boot\";
string filepath2 = filepath + #"\SystemErrors\somefile.text";
{
if (!Directory.Exists(filepath2))
Directory.CreateDirectory(#"c:\Windows\Boot\SystemErrors\somefile.txt");
if (!File.Exists(filepath2))
File.Create(filepath2);
}
Im trying to create a new folder and file.text, but nothing seems to work.
I don't think you're using the Exists methods correctly.
You must call File.Exists when you want to check if a file exists, and you must provide the path to the file.
Directory.Exists must be called when you want to check if a directory exists, and you must provide the path to the directory.
My application creates files and directories throughout the year and needs to access the timestamps of those directories to determine if it's time to create another one. So it's vital that when I move a directory I preserve its timestamps. I can do it like this when Directory.Move() isn't an option (e.g. when moving to a different drive).
FileSystem.CopyDirectory(sourcePath, targetPath, overwrite);
Directory.SetCreationTimeUtc (targetPath, Directory.GetCreationTimeUtc (sourcePath));
Directory.SetLastAccessTimeUtc(targetPath, Directory.GetLastAccessTimeUtc(sourcePath));
Directory.SetLastWriteTimeUtc (targetPath, Directory.GetLastWriteTimeUtc (sourcePath));
Directory.Delete(sourcePath, true);
However, all three of these "Directory.Set" methods fail if File Explorer is open, and it seems that it doesn't even matter whether the directory in question is currently visible in File Explorer or not (EDIT: I suspect this has something to do with Quick Access, but the reason isn't particularly important). It throws an IOException that says "The process cannot access the file 'C:\MyFolder' because it is being used by another process."
How should I handle this? Is there an alternative way to modify a timestamp that doesn't throw an error when File Explorer is open? Should I automatically close File Explorer? Or if my application simply needs to fail, then I'd like to fail before any file operations take place. Is there a way to determine ahead of time if Directory.SetCreationTimeUtc() for example will encounter an IOException?
Thanks in advance.
EDIT: I've made a discovery. Here's some sample code you can use to try recreating the problem:
using System;
using System.IO;
namespace CreationTimeTest
{
class Program
{
static void Main( string[] args )
{
try
{
DirectoryInfo di = new DirectoryInfo( #"C:\Test" );
di.CreationTimeUtc = DateTime.UtcNow;
Console.WriteLine( di.FullName + " creation time set to " + di.CreationTimeUtc );
}
catch ( Exception ex )
{
Console.WriteLine( ex );
//throw;
}
finally
{
Console.ReadKey( true );
}
}
}
}
Create C:\Test, build CreationTimeTest.exe, and run it.
I've found that the "used by another process" error doesn't always occur just because File Explorer is open. It occurs if the folder C:\Test had been visible because C:\ was expanded. This means the time stamp can be set just fine if File Explorer is open and C:\ was never expanded. However, once C:\Test becomes visible in File Explorer, it seems to remember that folder and not allow any time stamp modification even after C:\ is collapsed. Can anyone recreate this?
EDIT: I'm now thinking that this is a File Explorer bug.
I have recreated this behavior using CreationTimeTest on multiple Windows 10 devices. There are two ways an attempt to set the creation time can throw the "used by another process" exception. The first is to have C:\Test open in the main pane, but in that case you can navigate away from C:\Test and then the program will run successfully again. But the second way is to have C:\Test visible in the navigation pane, i.e. to have C:\ expanded. And once you've done that, it seems File Explorer keeps a handle open because the program continues to fail even once you collapse C:\ until you close File Explorer.
I was mistaken earlier. Having C:\Test be visible doesn't cause the problem. C:\Test can be visible in the main pane without issue. Its visibility in the navigation pane is what matters.
Try this:
string sourcePath = "";
string targetPath = "";
DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(sourcePath);
FileSystem.CopyDirectory(sourcePath, targetPath, overwrite);
DirectoryInfo targetDirectory = new DirectoryInfo(targetPath);
targetDirectory.CreationTimeUtc = sourceDirectoryInfo.CreationTimeUtc;
targetDirectory.LastAccessTimeUtc = sourceDirectoryInfo.LastAccessTimeUtc;
targetDirectory.LastWriteTimeUtc = sourceDirectoryInfo.LastWriteTimeUtc;
Directory.Delete(sourcePath, true);
This will allow you to set the creation/access/write times for the target directory, so long as the directory itself is not open in explorer (I am assuming it won't be, as it has only just been created).
I am suspecting FileSystem.CopyDirectory ties into Explorer and somehow blocks the directory. Try copying all the files and directories using standard C# methods, like this:
DirectoryCopy(#"C:\SourceDirectory", #"D:\DestinationDirectory", true);
Using these utility methods:
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName);
}
if ((dir.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
{
// Don't copy symbolic links
return;
}
var createdDirectory = false;
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
var newdir = Directory.CreateDirectory(destDirName);
createdDirectory = true;
}
// Get the files in the directory and copy them to the new location.
DirectoryInfo[] dirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
if ((file.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
continue; // Don't copy symbolic links
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
CopyMetaData(file, new FileInfo(temppath));
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
if (createdDirectory)
{
// We must set it AFTER copying all files in the directory - otherwise the timestamp gets updated to Now.
CopyMetaData(dir, new DirectoryInfo(destDirName));
}
}
private static void CopyMetaData(FileSystemInfo source, FileSystemInfo dest)
{
dest.Attributes = source.Attributes;
dest.CreationTimeUtc = source.CreationTimeUtc;
dest.LastAccessTimeUtc = source.LastAccessTimeUtc;
dest.LastWriteTimeUtc = source.LastWriteTimeUtc;
}
I need to create a directory, but, the directory when I need to create is inside of another directory. Something like this:
Directory.CreateDirectory(#"teste\teste\teste\teste\");
basically, this directory does not exist ( of course ), but, the CreateDirectory(...) not support this string style, how I can make to create this directories ?
My way to make this is that:
private void createdir(string _path)
{
string path = string.Empty;
string[] dir = _path.Split('\\');
for(int i=0;i<dir.Length;i++)
{
path += dir[i] + "\\";
Directory.CreateDirectory(path);
}
}
But, I want to know, if have a more better way to make this ( a more legible ) more rapid.
Directory.Create("c:\teste\teste\teste\teste"); should workt
according to MSDN, you can nest the directory . CreateDirectory
Directory.CreateDirectory("Public\\Html");
Directory.CreateDirectory("\\Users\\User1\\Public\\Html");
Directory.CreateDirectory("c:\\Users\\User1\\Public\\Html"); // using verbatim string you can escape slashes
if(System.IO.Directory.Exists(yourPath))
{
Directory.CreateDirectory(yourPath);
}
Directory.CreateDirectory() can be used to create directories and subdirectories as specified by the path.
Here’s an example:
static void Main(string[] args)
{
try
{
Directory.CreateDirectory(#"D:\ParentDir\ChildDir\SubChildDir\");
Console.WriteLine("Directories Created");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Source
My chosen method would be:
DirectoryInfo di = new DirectoryInfo(#"teste\teste\teste\teste\");
di.Create();
Your way is too complicated for this process. You don't have to use Split() method also to create this kind of directories.
You can use it like;
string tempFolderAbsolutePath = #"C:\Temp";
string subFolderRelativePath = #"teste\teste\teste\teste\";
DirectoryInfo tempFolder = new DirectoryInfo( tempFolderAbsolutePath );
DirectoryInfo subFolder = tempFolder.CreateSubdirectory( subFolderRelativePath );
As you can see, this process creates nested subdirectories.
If your current directory is (say C:\) and you want to create a directory as C:\A\B\C, then I think the best way is using
Directory.CreateDirectory(#"\A\B\C");
If you need a directory in another root (say, D:\) then you need to give the full path as
Directory.CreateDirectory(#"D:\A\B\C");
You do not need to have a for loop to create each directory as CreateDirectory does it for you.