Copy a file from local drive to shared drive using C# - c#

I want to copy a file from my local drive to a shared network path.
I have tried the following way:
string remoteUserName =
WebConfigurationManager.AppSettings["remoteUsername"].ToString();
string remotePassword =
WebConfigurationManager.AppSettings["remotePassword"].ToString();
string remoteDomain =
WebConfigurationManager.AppSettings["remoteDomain"].ToString();
string remoteFilePath =
WebConfigurationManager.AppSettings["remoteFilePath"].ToString();
using (var impersonation = new
ImpersonatedUser(remoteUserName, remoteDomain, remotePassword))
{
CreateErrorLog("Logged in successfully - User and password are correct.",
"Action" + " - " + "controllerName");
string filePath = remoteFilePath;
string fileName = "txt.txt";
StreamWriter SW1;
FileIOPermission myPerm = new
FileIOPermission(FileIOPermissionAccess.AllAccess, filePath + fileName);
myPerm.Assert();
SW1 = System.IO.File.CreateText(filePath + fileName);
}

Ok, let's work on this code a little. First let's simplify building the paths. We have a network path and a local path. According to your current code the network path is built with a few variables comboBox1, comboBox2, and Environment.UserName, so let's do it a little different:
var networkPath = Path.Combine(#"\\network",
comboBox1.SelectedItem as string,
comboBox2.SelectedItem as string,
Environment.UserName);
that's going to place the \ in between each of those strings properly (i.e. if there were already a back slash it wouldn't add one, but would if necessary).
Now let's do the same for the local path:
var localPath = Path.Combine(#"C:\Users",
Environment.UserName,
"test",
label5.Text);
ok, we're almost there, but we also have an alternative network path:
var alternativeNetworkPath = Path.Combine(#"\\atlanta2-0\it-documents\filestroage",
comboBox1.SelectedItem as string,
comboBox2.SelectedItem as string,
Environment.UserName,
label5.Text);
now, one thing about this path that's already suspect to me is this, \filestroage, that's actually spelled wrong. Now, if the folder is spelled that way fine, but I'm wondering if it's spelled wrong. So just take a look. Alright, let's continue on, now we have all three paths built, it's a little easier to read, and we can easily output those strings to ensure they are right. Let's take a look at the logic. It says this, if the networkPath exists then save it there, however, if it does not exist then create it and save it to the alternativeNetworkPath. So let's do that:
if (Directory.Exists(networkPath))
{
File.Copy(localPath, networkPath);
}
else
{
Directory.CreateDirectory(networkPath);
File.Copy(localPath, alternativeNetworkPath);
}
alright, simple enough yes? But you stated that the Directory.Exists is returning true even if it exists. That's pretty much expected isn't it? If the directory exists then this method would certainly return true, if not then it would return false. You then stated with the Directory.CreateDirectory that The line above says the network name cannot be found - that can only mean that the path was constructed wrong.
So after breaking it down, the bottom line is this, the paths being constructed have to be off a tidge. However, with this new model you should be able to pull those paths out a lot easier. So the entire method, in my mind, would look something like this:
var networkPath = Path.Combine(#"\\network",
comboBox1.SelectedItem as string,
comboBox2.SelectedItem as string,
Environment.UserName);
var localPath = Path.Combine(#"C:\Users",
Environment.UserName,
"test",
label5.Text);
var alternativeNetworkPath = Path.Combine(#"\\atlanta2-0\it-documents\filestroage",
comboBox1.SelectedItem as string,
comboBox2.SelectedItem as string,
Environment.UserName,
label5.Text);
if (Directory.Exists(networkPath))
{
File.Copy(localPath, networkPath);
}
else
{
Directory.CreateDirectory(networkPath);
File.Copy(localPath, alternativeNetworkPath);
}
and so now let's have a look at those paths in those variables and your problem should come right out.

Network paths are accessed by full Universal Naming Convention-UNC \\Server\Share\drive\file paths. If you have these type credentials or rights to access network, You could use File.Copy method to move your files.

Related

How to convert a local file path in PC to a Network Relative or UNC path?

String machineName = System.Environment.MachineName;
String filePath = #"E:\folder1\folder2\file1";
int a = filePath.IndexOf(System.IO.Path.DirectorySeparatorChar);
filePath = filePath.Substring(filePath.IndexOf(System.IO.Path.DirectorySeparatorChar) +1);
String networdPath = System.IO.Path.Combine(string.Concat(System.IO.Path.DirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar), machineName, filePath);
Console.WriteLine(networdPath);
I wrote the above code using String.Concat and Path.Combine to get network path. But it is just a workaround and not a concrete solution and may fail.
Is there a concrete solution for getting a network path?
You are assuming that your E:\folder1 local path is shared as \\mypc\folder1, which in general is not true, so I doubt a general method that does what you want to do exists.
You are on the right path in implementing what you are trying to achieve. You can get more help from System.IO.Path; see Path.GetPathRoot on MSDN for returned values according to different kind of path in input
string GetNetworkPath(string path)
{
string root = Path.GetPathRoot(path);
// validate input, in your case you are expecting a path starting with a root of type "E:\"
// see Path.GetPathRoot on MSDN for returned values
if (string.IsNullOrWhiteSpace(root) || !root.Contains(":"))
{
// handle invalid input the way you prefer
// I would throw!
throw new ApplicationException("be gentle, pass to this function the expected kind of path!");
}
path = path.Remove(0, root.Length);
return Path.Combine(#"\\myPc", path);
}

C# Why does System.IO.File.Exists keep coming up false?

string profile = "\\" + txtProfileLoad.Text + ".txt";
profile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + profile;
The variable profile is receiving the correct file path, but when I run it the File.Exists comes up false every time.
if (System.IO.File.Exists(profile) == true)
{
System.IO.StreamReader profileReader;
profileReader = new System.IO.StreamReader(profile);
do
{
profileLevel = profileLevel + profileReader.ReadLine() + "\r\n";
} while (profileReader.Peek() != -1);
loadName(profileLevel);
wordBeingUsed.finalWord = loadedName;
Close();
}
else
{
MessageBox.Show("Invalid file name. Please try again.");
}
There aren't any permissions stopping it from seeing the file.
Any help with this would be appreciated. It's been driving me crazy.
Is this a pre-existing file that you are trying to read? Or is this a new file that you are hoping to create? What is the value inside txtProfileLoad.Text, issue most likely is within this property.
Run a sanity check:
var profile = "mytestfile.txt";
var myFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), profile);
File.WriteAllText(myFile, "Testing file write");
if (File.Exists(myFile))
{
// Access works.
}
else
{
//Didn't work
}
If above code works, then it is most likely that the name you create from txtProfileLoad.Text is different from actual file on the drive. On the other hand, if this is a file that doesn't exist yet; then of course it would return false when you check Exists.
You can use a string variable and pass the file name to it:
string tempFile = txtProfileLoad.Text;
string profile = #"C:\temp\tempfile.txt";
Also check out if you could use the file open method instead of File.Exist.
As per MSDN:
true if the caller has the required permissions and path contains the name of an existing file; otherwise, false. This method also
returns false if path is Nothing, an invalid path, or a zero-length
string. If the caller does not have sufficient permissions to read the
specified file, no exception is thrown and the method returns false
regardless of the existence of path.
Have you tried running as an administrator? Try do "right click" on the Visual Studio icon and select "Run as Administrator", and see if you still encounter the same behaviour.

How to navigate a few folders up?

One option would be to do System.IO.Directory.GetParent() a few times. Is there a more graceful way of travelling a few folders up from where the executing assembly resides?
What I am trying to do is find a text file that resides one folder above the application folder. But the assembly itself is inside the bin, which is a few folders deep in the application folder.
Other simple way is to do this:
string path = #"C:\Folder1\Folder2\Folder3\Folder4";
string newPath = Path.GetFullPath(Path.Combine(path, #"..\..\"));
Note This goes two levels up. The result would be:
newPath = #"C:\Folder1\Folder2\";
Additional Note
Path.GetFullPath normalizes the final result based on what environment your code is running on windows/mac/mobile/...
if c:\folder1\folder2\folder3\bin is the path then the following code will return the path base folder of bin folder
//string directory=System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString());
string directory=System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString();
ie,c:\folder1\folder2\folder3
if you want folder2 path then you can get the directory by
string directory = System.IO.Directory.GetParent(System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString()).ToString();
then you will get path as c:\folder1\folder2\
You can use ..\path to go one level up, ..\..\path to go two levels up from path.
You can use Path class too.
C# Path class
This is what worked best for me:
string parentOfStartupPath = Path.GetFullPath(Path.Combine(Application.StartupPath, #"../"));
Getting the 'right' path wasn't the problem, adding '../' obviously does that, but after that, the given string isn't usable, because it will just add the '../' at the end.
Surrounding it with Path.GetFullPath() will give you the absolute path, making it usable.
public static string AppRootDirectory()
{
string _BaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
return Path.GetFullPath(Path.Combine(_BaseDirectory, #"..\..\"));
}
Maybe you could use a function if you want to declare the number of levels and put it into a function?
private String GetParents(Int32 noOfLevels, String currentpath)
{
String path = "";
for(int i=0; i< noOfLevels; i++)
{
path += #"..\";
}
path += currentpath;
return path;
}
And you could call it like this:
String path = this.GetParents(4, currentpath);
C#
string upTwoDir = Path.GetFullPath(Path.Combine(System.AppContext.BaseDirectory, #"..\..\"));
The following method searches a file beginning with the application startup path (*.exe folder). If the file is not found there, the parent folders are searched until either the file is found or the root folder has been reached. null is returned if the file was not found.
public static FileInfo FindApplicationFile(string fileName)
{
string startPath = Path.Combine(Application.StartupPath, fileName);
FileInfo file = new FileInfo(startPath);
while (!file.Exists) {
if (file.Directory.Parent == null) {
return null;
}
DirectoryInfo parentDir = file.Directory.Parent;
file = new FileInfo(Path.Combine(parentDir.FullName, file.Name));
}
return file;
}
Note: Application.StartupPath is usually used in WinForms applications, but it works in console applications as well; however, you will have to set a reference to the System.Windows.Forms assembly. You can replace Application.StartupPath by
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) if you prefer.
I use this strategy to find configuration and resource files. This allows me to share them for multiple applications or for Debug and Release versions of an application by placing them in a common parent folder.
Hiding a looped call to Directory.GetParent(path) inside an static method is the way to go.
Messing around with ".." and Path.Combine will ultimately lead to bugs related to the operation system or simply fail due to mix up between relative paths and absolute paths.
public static class PathUtils
{
public static string MoveUp(string path, int noOfLevels)
{
string parentPath = path.TrimEnd(new[] { '/', '\\' });
for (int i=0; i< noOfLevels; i++)
{
parentPath = Directory.GetParent(parentPath ).ToString();
}
return parentPath;
}
}
this may help
string parentOfStartupPath = Path.GetFullPath(Path.Combine(Application.StartupPath, #"../../")) + "Orders.xml";
if (File.Exists(parentOfStartupPath))
{
// file found
}
If you know the folder you want to navigate to, find the index of it then substring.
var ind = Directory.GetCurrentDirectory().ToString().IndexOf("Folderame");
string productFolder = Directory.GetCurrentDirectory().ToString().Substring(0, ind);
I have some virtual directories and I cannot use Directory methods. So, I made a simple split/join function for those interested. Not as safe though.
var splitResult = filePath.Split(new[] {'/', '\\'}, StringSplitOptions.RemoveEmptyEntries);
var newFilePath = Path.Combine(filePath.Take(splitResult.Length - 1).ToArray());
So, if you want to move 4 up, you just need to change the 1 to 4 and add some checks to avoid exceptions.
Path parsing via System.IO.Directory.GetParent is possible, but would require to run same function multiple times.
Slightly simpler approach is to threat path as a normal string, split it by path separator, take out what is not necessary and then recombine string back.
var upperDir = String.Join(Path.DirectorySeparatorChar, dir.Split(Path.DirectorySeparatorChar).SkipLast(2));
Of course you can replace 2 with amount of levels you need to jump up.
Notice also that this function call to Path.GetFullPath (other answers in here) will query whether path exists using file system. Using basic string operation does not require any file system operations.

Check if a file exists on the server

I am trying to check if a file is on the server with the C# code behind of my ASP.NET web page. I know the file does exist as I put it on the server in a piece of code before hand. Can anyone see why it is not finding the file. This is the code:
wordDocName = "~/specifications/" + Convert.ToInt32(ViewState["projectSelected"]) + ".doc";
ViewState["wordDocName"] = wordDocName;
if (File.Exists(wordDocName))
{
btnDownloadWordDoc.Visible = true;
}
else
{
btnDownloadWordDoc.Visible = false;
}
the file path should be physical not virtual. Use
if (File.Exists(Server.MapPath(wordDocName)))
File.Exists() and probably everything else you want to do with the file will need a real Path.
Your wordDocName is a relative URL.
Simply use
string fileName = Server.MapPath(wordDocName);
Use
Server.MapPath("~/specifications/" + Convert.ToInt32(ViewState["projectSelected"]) + ".doc")
to get the fully-qualified path. That should do the trick for ya.
You need to use Server.MapPath e.g.
wordDocName = Server.MapPath("~/specifications/" + Convert.ToInt32(ViewState["projectSelected"]) + ".doc");
ViewState["wordDocName"] = wordDocName;
if (File.Exists(wordDocName))
{
btnDownloadWordDoc.Visible = true;
}
else
{
btnDownloadWordDoc.Visible = false;
}
this might not work if the directory holding the file is referenced by a junction/symbolic link. I have this case in my own application and if I put the REAL path to the file, File.Exists() returns true. But if I use Server.MapPath but the folder is in fact a junction to the folder, it seems to fail. Anyone experienced the same behaviour?
The character "~" is a special char in ASP.NET to get virtual path specifications and simply means "root directory of the application". Is is not understood by the .NET BCL like the File API and must be mapped first into a physical path with Server.MapPath() as others stated.
You have to convert the path to a physical path with Server.MapPath(relativePath)
if (File.Exists(filePath))
wordDocName = "~/specifications/" + ViewState["projectSelected"] + ".doc";
btnDownloadWordDoc.Visible = File.Exists(Server.MapPath(wordDocName));
string docname="traintatkalantnoy.txt";
string a = (Server.MapPath(docname));
if (File.Exists(a))

Replacing delimiter characters in file path

I'm developing a C# web application in VS 2008. I let the user select an input file and then I store the file path in a string variable. However, it stores this path as "C:\\folder\\...". So my question is how do I convert this file path into single "\"?
Thank you guys for all your helps! Please forgive me as I am a newbie to ASP.NET development. This is more of my code in context. First I want to see if the directory exists. I guess I don't have to check this if I check if the file exists. But this should still work right? And currently my "path" string variable is not showing up the way I need it to. I'm not sure how to formulate this statement. Eventually I want to execute the ReadAllText statement (see the last line).
protected void btnAppend_Click(object sender, EventArgs e)
{
string fullpath = Page.Request.PhysicalPath;
string fullPath2 = fullpath.Replace(#"\\", #"\");
if (!Directory.Exists(fullpath2))
{
string msg = "<h1>The upload path doesn't exist: {0}</h1>";
Response.Write(String.Format(msg, fullpath2));
Response.End();
}
string path = "#" + fullpath2 + uploadFile.PostedFile.FileName;
if (File.Exists(path))
{
// Create a file to write to.
try
{
StreamReader sr = new StreamReader(path);
string s = "";
while(sr.Peek() > 0)
s = sr.ReadLine();
sr.Close();
}
catch (IOException exc)
{
Console.WriteLine(exc.Message + "Cannot open file.");
return;
}
}
if (uploadFile.PostedFile.ContentLength > 0)
{
inputfile = System.IO.File.ReadAllText(path);
Are you sure the problem is the backslashes? Backslash is an escape character in strings, such that if you were adding it in a string you have to type it as "\\" rather than "\". (if you don't use #) Note that the debugger frequently displays the string the way you would put it in code, with the escape characters, rather than direct.
According to the documentation, Page.Request.PhysicalPath returns the path to the specific file you are in, not the directory. Directory.Exists is only true if you give it a directory, not a file. Does File.Exists() return true?
For a start, calling fullpath.Replace() does nothing to fullpath; it returns a new string. Also, when your string literals have a \ (backslash) in them, you need to tell the compiler that you're not trying to use an escape sequence:
fullpath = fullpath.Replace(#"\\", #"\");
The # means "please treat this string literally (verbatim)". In other words, "when I say backslash, I mean backslash!"
See http://msdn.microsoft.com/en-us/library/362314fe.aspx.
Edit:
As LeBleu mentioned, you are calling Directory.Exists() on a full filepath. This won't work; you need to extract the directory part from the path. Try this:
if (!Directory.Exists(Path.GetDirectoryName(fullpath)))
{
...
}
You might want to consider replacing it with the Path.DirectorySeparatorChar rather than \ on the offchance that your code may end up running on a different platform one day (mono.net allows it to be run on linux or possibly more likely it might end up on some wierd mobile platform)
http://msdn.microsoft.com/en-us/library/system.io.path.directoryseparatorchar.aspx

Categories