c# building strings domains - c#

I am trying to download images. Their link may be image.png or http://www.example.com/image.png.
I made the image.png be added to the host and passed it to a list. So image.png is now http://www.example.com/image.png
But if the other type is used what I get is http://www.example.com//http://www.example.com/image.png
All I need is to get the string after the third slash. Here is some code I am tried to use:
try
{
path = this.txtOutput.Text + #"\" + str4 + etc;
client.DownloadFile(str, path);
}
catch(Exception e)
{
var uri = new Uri(str);
String host = (String) uri.Host;
String pathToFile = "http://" + host + "/";
int len = pathToFile.Length;
String fin = str.Substring(len, str.Length - len);
path = this.txtOutput.Text + #"\" + str4 + etc;
client.DownloadFile(fin, path);
}

What are these variables all about, like str4, etc and so on? Instead of the try catch you could check wheter the string is a valid uri. Give a look here. Try to debug you code line on line and check every single variable, then you will see which line makes the mistake.
EDIT
If I understodd you right, then this would be your solution:
string wrongResult = "example.com//http://www.example.com/image.png";
string shouldResult = "example.com/image.png";
int listIndexOfHttp = wrongResult.LastIndexOf("http:");
string correctResult = wrongResult.Substring(listIndexOfHttp);
When not please describe more specific from where you get this and it is always the same structure? or alaways different?

Related

Exclude Sub Folder Within Directory C#

I wanted to exclude a folder within directory when copying the directory to other location could anyone please help me out ?
string logZipTarget = "PangaeaLogs_Fail_" + currentLocation + "_" + classID + "_" + tracer + "_" +
DateTime.Now.ToString("ddMMMyyyy-HH-mm-ss", System.Globalization.CultureInfo.InvariantCulture) + ".zip";
string buildTypeFile = #"C:\build.typ";
string journalFile = #"C:\Mavis\" + tracer + ".ejl";
string logsPath = #"C:\Pangaea\PangaeaFinancialLogs\"; //Path to copy directory to
File.Copy(buildTypeFile, logsPath + "build.typ", true);
File.Copy(journalFile, logsPath + tracer + ".ejl", true);
Helper.DirectoryCopy(#"C:\Program Files\NCR\Pangaea\", logsPath, true);
executor.ZipFolder(logsPath, logZipTarget);
Inside this location C:\Pangaea\PangaeaFinancialLogs\ApplicationData i wanted to remove this folder SessionBackup but what is happening is it is copyin all the folders inside this location
string logsPath = #"C:\Pangaea\PangaeaFinancialLogs\";
From the bit of code provided in your comment I can only assume which classes your using. If I'm correct this should do the trick:
DirectoryInfo currentFolder = new DirectoryInfo("");
String NameOfFolderNotToInclude = "";
if(currentFolder.Name != NameOfFolderNotToInclude)
{
File.Copy(newPath, newPath.Replace(#"\\xxx\yyy", #"C:\bbb"), true);
}
Always keep in mind that equals (MSDN) if not overidden will always compare the actual objects for equality. In your case a string will never be the same as a DirectoryInfo and thus not be equal even if the DirectoryInfo is pointing at the location the string describes.

C# Filter differences from a path

DirectoryPath = C:\Pics
filePath = C:\Pics\Dogs\dog.PNG
newPath should be: Dogs\dog.PNG
How do I get the newPath?
My code snippet is not right
string directoryPath = "C:\\Pics";
string filePath = "C:\\Pics\\Dogs\\dog.PNG";
if (!directoryPath.EndsWith("\\"))
directoryPath = directoryPath + "\\";
string newPath = filePath.Substring(filePath.LastIndexOf(directoryPath) + 1);
Thanks in advance!
Could you append a backslash to the directory path & then in the filepath replace the directory path with an empty string
newPath = filePath.Replace(DirectoryPath + #"\", string.Empty);
If the directoryPath does not match the start of the filePath, then newPath will be unchanged.
I did post this before you edited your code to show the conditional adding of the backslash - so that can be removed in the above code.
The int Index you get from LastIndexOf() will always starts with the rightmost value, in your case 0. You have also to add the String.Lenght for this.
if (filePath.StartsWith(directoryPath))
{
string newPath =
filePath.Substring(filePath.LastIndexOf(directoryPath) + directoryPath.Length + 1);
}
I would first check if filePath contains DirectoryPath,so i'd do something like this:
var newPath=filePath.Contains(DirectoryPath)?filePath.Substring(DirectoryPath.Length + 1)
:filePath;
Or even better,using StartsWith
var newPath=filePath.StartsWith(DirectoryPath)?filePath.Substring(DirectoryPath.Length + 1)
:filePath;

Versioning file name and saving it to different location

After the else block Path.Combine method combines every part and gives the file name when Console.WriteLine(result); is used. But it doesn't actually create the file with that name.
I want to get the EmployeeDetails.txt file, make a version of it (i.e. renaming the filename) and saves it to C:\Hitory folder.
How to achieve that?
Using File.Move throws FileNotFoundexception
void ModRec()
{
string filename = #"C:\Current\EmployeeDetails.txt";
string current = #"C:\Current\";
string history = #"C:\History\";
FileInfo fileinfo = new FileInfo(filename);
if (fileinfo.Exists)
{
if (!Directory.Exists(history))
{
Directory.CreateDirectory(history);
}
}
else
{
Console.WriteLine("\t\t\tFile doesn't exist!");
Console.ReadLine();
Menu1();
}
var extension = Path.GetExtension(filename);
var fileNamePart = Path.GetFileNameWithoutExtension(filename);
var path = Path.GetDirectoryName(filename);
var version = 0;
string result;
do
{
version++;
result = Path.Combine(path, fileNamePart + "_" + version + extension);
}
while (File.Exists(result));
//File.Move(current, history);
}
Your loop at the end needs to change slightly, because
result = Path.Combine(path, fileNamePart + "_" + version + extension);
is looking in the directory where the file already is, rather than in the history directory where you want it to be, so you'll be scanning for duplicates in the wrong location. The Path.Combine therefore needs to reference the value of history:
result = Path.Combine(history, fileNamePart + "_" + version + extension);
Secondly, you cannot use Move to move a file to a directory in the same way that you can from the command line, you need to specify the two parameters as filenames, so
File.Move(current, history);
becomes
File.Move(filename, result);
The resulting code at the end of your method should therefore look like this:
do
{
version++;
result = Path.Combine(history, fileNamePart + "_" + version + extension);
}
while (File.Exists(result));
File.Move(filename, result);
Incidentally, where you test whether the file already exists, you simply call Menu1 and then carry on. Can you guarantee that that will ensure that the next thing that the user does will create a valid file? I'm guessing that it most likely cannot guarantee that, so you should exit your method at that point, or perhaps put the remainder of the body inside the fileinfo.Exists block.
That leaves the desirability of invoking a menu from inside this method, but that's a design question outside of the scope of what you've asked here.
Try this instead:
void ModRec()
{
string filename = #"C:\Current\EmployeeDetails.txt";
string current = #"C:\Current\";
string history = #"C:\History\";
FileInfo fileinfo = new FileInfo(filename);
if (fileinfo.Exists)
{
if (!Directory.Exists(history))
{
Directory.CreateDirectory(history);
}
}
else
{
Console.WriteLine("\t\t\tFile doesn't exist!");
Console.ReadLine();
Menu1();
}
var extension = Path.GetExtension(filename);
var fileNamePart = Path.GetFileNameWithoutExtension(filename);
var path = Path.GetDirectoryName(filename);
var version = 0;
string result;
do
{
version++;
result = Path.Combine(history, fileNamePart + "_" + version + extension);
}
while (File.Exists(result));
File.Move(filename, result);
}
Path.Combine() does not touch filesystem at all. No files/folders would be ever crated.
Try File.Move(filename, history);. That is, instead of current, which is a directory, move the file (assuming filename is a full path).

c# service renaming files!

I have a windows service , that takes files with metadata(FIDEF) and corresponding video file and , translates the XML(FIDEF) using XSLT .
I get the file directory listing for FIDEF's and if a video file of the same name exists it translates it. That works ok , but it is on a timer to search every minute. I am trying to handle situations where the same file name enters the input directory but is already in the output directory. I just have it changing the output name to (copy) thus if another file enters i should get (copy)(copy).mov but the service won't start with filenames of the same directory already in the output , it works once and then does not seem to pick up any new files.
Any Help would be great as I have tried a few things with no good results. I believe its the renaming methods, but I've put most of the code up in case its a clean up issue or something else.
(forgive some of the names just trying different things).
private void getFileList()
{
//Get FILE LIST FROM Directory
try
{
// Process Each String/File In Directory
string result;
//string filename;
filepaths = null;
filepaths = Directory.GetFiles(path, Filetype);
foreach (string s in filepaths)
{
for (int i = 0; i < filepaths.Length; i++)
{
//Result Returns Video Name
result = Path.GetFileNameWithoutExtension(filepaths[i]);
FileInfo f = new FileInfo(filepaths[i]);
PreformTranslation(f, outputPath + result , result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error " + e);
}
}
private void MoveVideoFiles(String Input, String Output)
{
File.Move(Input, Output);
}
private string GetUniqueName(string name)
{
//Original Filename
String ValidName = name;
//remove FIDEF from filename
String Justname1 = Path.GetFileNameWithoutExtension(name);
//get .mov extension
String Extension2 = Path.GetExtension(Justname1);
//get filename with NO extensions
String Justname = Path.GetFileNameWithoutExtension(Justname1);
//get .Fidef
String Extension = Path.GetExtension(name);
int cnt = 0;
//string[] FileName = Justname.Split('(');
//string Name = FileName[0];
while (File.Exists(ValidName)==true)
{
ValidName = outputPath + Justname + "(Copy)" + Extension2 + Extension;
cnt++;
}
return ValidName;
}
private string getMovFile(string name)
{
String ValidName = name;
String Ext = Path.GetExtension(name);
String JustName = Path.GetFileNameWithoutExtension(name);
while(File.Exists(ValidName))
{
ValidName = outputPath + JustName + "(Copy)" + Ext;
}
return ValidName;
}
//Preforms the translation requires XSL & FIDEF name.
private void PreformTranslation(FileInfo FileName, String OutputFileName , String result)
{
string FidefName = OutputFileName + ".FIDEF";
String CopyName;
String copyVidName = outputPath + result;
XslCompiledTransform myXslTransform;
myXslTransform = new XslCompiledTransform();
try
{
myXslTransform.Load(XSLname);
}
catch
{
EventLog.WriteEntry("Error in loading XSL");
}
try
{ //only process FIDEF's with corresponding Video file
if (AllFidef == "no")
{
//Check if video exists if yes,
if (File.Exists(path + result))
{
//Check for FIDEF File Already Existing in the Output Directory.
if (File.Exists(FidefName))
{
//Get unique name
CopyName = GetUniqueName(FidefName);
copyVidName= getMovFile(copyVidName);
//Translate and create new FIDEF.
//double checking the file is here
if (File.Exists(outputPath + result))
{
myXslTransform.Transform(FileName.ToString(), CopyName);
File.Delete(FileName.ToString());
MoveVideoFiles(path + result, copyVidName);
}
////Move Video file with Corresponding Name.
}
else
{ //If no duplicate file exsists in Directory just move.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
MoveVideoFiles(path + result, outputPath + result);
}
}
}
else
{
//Must have FIDEF extension
//Processes All FIDEFS and moves any video files if found.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error Transforming " + "FILENAME = " + FileName.ToString()
+ " OUTPUT_FILENAME = " + OutputFileName + "\r\n" +"\r\n"+ e);
}
}
There is a lot wrong with your code. getFileList has the unneeded inner for loop for starters. Get rid of it. Your foreach loop has s, which can replace filepaths[i] from your for loop. Also, don't do outputPath + result to make file paths. Use Path.Combine(outputPath, result) instead, since Path.Combine handles directory characters for you. Also, you need to come up with a better name for getFileList, since that is not what the method does at all. Do not make your method names liars.
I would simply get rid of MoveVideoFiles. The compiler just might too.
GetUniqueName only works if your file name is of the form name.mov.fidef, which I'm assuming it is. You really need better variable names though, otherwise it will be a maintenance nightware later on. I would get rid of the == true in the while loop condition, but that is optional. The assignment inside the while is why your files get overwritten. You always generate the same name (something(Copy).mov.fidef), and as far as I can see, if the file exists, I think you blow the stack looping forever. You need to fix that loop to generate a new name (and don't forget Path.Combine). Maybe something like this (note this is untested):
int copyCount = 0;
while (File.Exists(ValidName))
{
const string CopyName = "(Copy)";
string copyString = copyCount == 0 ? CopyName : (CopyName + "(" + copyCount + ")");
string tempName = Justname + copyString + Extension2 + Extension;
ValidName = Path.Combine(outputPath, tempName);
copyCount++;
}
This generates something(Copy).mov.fidef for the first copy, something(Copy)(2).mov.fidef for the second, and so on. Maybe not what you want, but you can make adjustments.
At this point you have a lot to do. getMovFile looks as though it could use work in the same manner as GetUniqueName. You'll figure it out. Good luck.

File.Move() rename not working

My app takes "unclean" file names and "cleans" them up. "Unclean" file names contain characters like #, #, ~, +, %, etc. The "cleaning" process replaces those chars with "". However, I found that if there are two files in the same folder that, after a cleaning, will have the same name, my app does not rename either file. (I.e. ##test.txt and ~test.txt will both be named test.txt after the cleaning).
Therefore, I put in a loop that basically checks to see if the file name my app is trying to rename already exists in the folder. However, I tried running this and it would not rename all the files. Am I doing something wrong?
Here's my code:
public void FileCleanup(List<string> paths)
{
string regPattern = (#"[~#&!%+{}]+");
string replacement = "";
Regex regExPattern = new Regex(regPattern);
List<string> existingNames = new List<string>();
StreamWriter errors = new StreamWriter(#"C:\Documents and Settings\joe.schmoe\Desktop\SharePointTesting\Errors.txt");
StreamWriter resultsofRename = new StreamWriter(#"C:\Documents and Settings\joe.schmoe\Desktop\SharePointTesting\Results of File Rename.txt");
var filesCount = new Dictionary<string, int>();
string replaceSpecialCharsWith = "_";
foreach (string files2 in paths)
try
{
string filenameOnly = Path.GetFileName(files2);
string pathOnly = Path.GetDirectoryName(files2);
string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
string sanitized = Path.Combine(pathOnly, sanitizedFileName);
if (!System.IO.File.Exists(sanitized))
{
System.IO.File.Move(files2, sanitized);
resultsofRename.Write("Path: " + pathOnly + " / " + "Old File Name: " + filenameOnly + "New File Name: " + sanitized + "\r\n" + "\r\n");
}
else
{
existingNames.Add(sanitized);
foreach (string names in existingNames)
{
string sanitizedPath = regExPattern.Replace(names, replaceSpecialCharsWith);
if (filesCount.ContainsKey(sanitizedPath))
{
filesCount[names]++;
}
else
{
filesCount.Add(sanitizedPath, 1);
}
string newFileName = String.Format("{0},{1}, {2}", Path.GetFileNameWithoutExtension(sanitizedPath),
filesCount[sanitizedPath] != 0
? filesCount[sanitizedPath].ToString()
: "",
Path.GetExtension(sanitizedPath));
string newFilePath = Path.Combine(Path.GetDirectoryName(sanitizedPath), newFileName);
System.IO.File.Move(names, newFileName);
}
}
}
catch (Exception e)
{
//write to streamwriter
}
}
}
Anybody have ANY idea why my code won't rename duplicate files uniquely?
You do foreach (string names in existingNames), but existingNames is empty.
You have your if (System.IO.File.Exists(sanitized)) backwards: it makes up a new name if the file doesn't exist, instead of when it exists.
You make a string newFileName, but still use sanitizedPath instead of newFileName to do the renaming.
The second parameter to filesCount.Add(sanitizedPath, 0) should be 1 or 2. After all, you have then encountered your second file with the same name.
If filesCount[sanitizedPath] equals 0, you don't change the filename at all, so you overwrite the existing file.
In addition to the problem pointed out by Sjoerd, it appears that you are checking to see if the file exists and if it does exist you move it. Your if statement should be
if (!System.IO.File.Exists(sanitized))
{
...
}
else
{
foreach (string names in existingNames)
{
...
}
}
}
Update:
I agree that you should split the code up into smaller methods. It will help you identify which pieces are working and which aren't. That being said, I would get rid of the existingNames list. It is not needed because you have the filesCount Dictionary. Your else clause would then look something like this:
if (filesCount.ContainsKey(sanitized))
{
filesCount[sanitized]++;
}
else
{
filesCount.Add(sanitized, 1);
}
string newFileName = String.Format("{0}{1}.{2}",
Path.GetFileNameWithoutExtension(sanitized),
filesCount[sanitized].ToString(),
Path.GetExtension(sanitized));
string newFilePath = Path.Combine(Path.GetDirectoryName(sanitized), newFileName);
System.IO.File.Move(files2, newFileName);
Please note that I changed your String.Format method call. You had some commas and spaces in there that looked incorrect for building a path, although I could be missing something in your implementation. Also, in the Move I changed the first argument from "names" to "files2".
A good way to make the code less messy would be to split it to methods as logical blocks.
FindUniqueName(string filePath, string fileName);
The method would prefix the fileName with a character, until the fileName is unique withing the filePath.
MoveFile(string filePath, string from, string to);
The method would use the FindUniqueName method if the file already exists.
It would be way easier to test the cleanup that way.
Also you should check if a file actually requires renaming:
if (String.Compare(sanitizedFileName, filenameOnly, true) != 0)
MoveFile(pathOnly, fileNameOnly, sanitizedFileName);
private string FindUniqueName(string fileDirectory, string from, string to)
{
string fileName = to;
// There most likely won't be that many files with the same name to reach max filename length.
while (File.Exists(Path.Combine(fileDirectory, fileName)))
{
fileName = "_" + fileName;
}
return fileName;
}
private void MoveFile(string fileDirectory, string from, string to)
{
to = FindUniqueName(fileDirectory, from, to);
File.Move(Path.Combine(fileDirectory, from), Path.Combine(fileDirectory, to));
}

Categories