Can't move multiple files in a directory - c#

I am trying to move multiple files in a directory to an archive sub folder. I used a foreach loop to do the idea. Unfortunately, It can only move a file if there is only one file in the directory. But when I put multiple in the directory the Directory.move(); won't work. Can anyone help me?
static string antJsonSerializer(){
#region KDI SALES
string[] allfiles = Directory.GetFiles(#"C:\xml\"); // Put all file names in root directory into array.
string sourceDirectory = #"C:\xml\";
string destinationDirectory = #"C:\xml\Archive\";
// Check if directories are existing -- Working
bool xmlRoot = System.IO.Directory.Exists(sourceDirectory);
if (!xmlRoot) System.IO.Directory.CreateDirectory(sourceDirectory);
bool xmlArchive = System.IO.Directory.Exists(destinationDirectory);
if (!xmlArchive) System.IO.Directory.CreateDirectory(destinationDirectory);
AntHelpers drone = new AntHelpers();
foreach (string name in allfiles)
{
try
{
drone.xmltosql(#name.Trim());
//File.Move(#name, destinationDirectory + (DateTime.Now.Year).ToString() + (DateTime.Now.Month).ToString().PadLeft(2, '0') + (DateTime.Now.Day).ToString().PadLeft(2, '0') + (DateTime.Now.Hour).ToString().PadLeft(2, '0') + ".html"); //Not working
Directory.Move(#name, destinationDirectory + (DateTime.Now.Year).ToString() + (DateTime.Now.Month).ToString().PadLeft(2, '0') + (DateTime.Now.Day).ToString().PadLeft(2, '0') + (DateTime.Now.Hour).ToString().PadLeft(2, '0') + ".html");
//Directory.Move(sourceDirectory, destinationDirectory); //Not working
}
catch (Exception e)
{
//Console.WriteLine("Main Process Catch ERR: " + e.Message);
//ErrLogtoDB(string TRNTYPE, string extserial, string texttowrite, string logfilename)
AntHelpers.ErrLogtoDB("SALES", #name, "Ant JSON Serializer Failed: " + e.Message,
"LeafCutterLogFile_JSONSerializer_" + (DateTime.Now.Year).ToString() + (DateTime.Now.Month).ToString().PadLeft(2, '0') + (DateTime.Now.Day).ToString().PadLeft(2, '0') + (DateTime.Now.Hour).ToString().PadLeft(2, '0') + ".html");
}
//drone.ExtractSQLSendAntHill(); //For testing: OFF
#endregion
return " !!!! Work Complete !!!! ";
}

You are trying to save a file with year + month + day + hour.html as "NAME". If multiple files are there, then how can you save it with same file name? Instead you should add seconds and/or milliseconds, or use something else to distinguish the file and make it a unique name. Otherwise, take file name without the extension then add year, month, day, and hour. That is why you are not able to move multiple files at a time, because when try to move the second file an exception will be thrown say "unable to move an existing file."

Directory.Move takes a source and destination directory, not a file path. Try this:
Directory.Move(sourceDirectory, destinationDirectory);
Also, it can be run at the very end - after the foreach loop.

Related

Moving files to corresponding folder [duplicate]

This question already has an answer here:
Moving files using SSIS and Script Component
(1 answer)
Closed 4 years ago.
I'm using C# language for finding certain files and moving them to corresponding folder. I'm using this code bellow, but files that I'm getting lately cannot be read with this code. Before name of the file would be for example "File_20141120", but files that I'm getting now are named, for example: ABC (222), ACD (2), DES (33), so I need to write a code that will read numbers in parentheses and move it to folder with the same number.
The code I'm using right now:
public void Main()
{
string filename;
string datepart;
bool FolderExistFlg;
filename = Dts.Variables["User::FileName"].Value.ToString();
datepart = (filename.Substring(filename.Length - 12)).Substring(0, 8);
FolderExistFlg = Directory.Exists(Dts.Variables["OutputMainFolder"].Value.ToString() + "\\" + datepart);
if (!FolderExistFlg)
{
Directory.CreateDirectory(Dts.Variables["OutputMainFolder"].Value.ToString() + "\\" + datepart);
}
File.Move(Dts.Variables["SourceFolder"].Value.ToString() + "\\" + filename,
Dts.Variables["OutputMainFolder"].Value.ToString() + "\\" + datepart + "\\" + filename);
Dts.TaskResult = (int)ScriptResults.Success;
}
#region ScriptResults declaration
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
SSIS is optimized for the task you are performing. If we assume that all files in the source folder need to be moved, then place the file task in a for each loop and parameterize the source and destination variables.
Create five variables:
SourceFolder
DestinationFolder
FileName
SourceFileNameWithPath = SourceFolder + "\" + FileName
DestinationFileNameWithPath = DestinationFolder + "\" + FileName
Use the ForEach loop to loop over the SourceFolder and read in each file name (select File Name and Extension) into the FileName variable (note: set FileSpec to either . or *.) . In the File Task, set the source variable to SourceFileNameWithPath and the destination variable to DestinationFileNameWithPath.
The File System Task should be Rename File.
https://www.tutorialgateway.org/move-multiple-files-using-file-system-task-in-ssis/
It sounds like you're asking how to extract the folder name from between the two parens (). If that's the case, a simple RegEx will work for you:
// Extracts only the number between the parens
// E.g. Filename: aaa (333)
// Output: 333
var folderNumber = Regex.Match(
filename,
#"\(([^)]*)\)").Groups[1].Value;

FileInfo.GetFiles() and special characters (accents)

When I insert in DB a string that contains special character as a "à" or a "é" from a FileInfo.GetFiles() item, I get issues and SQL save splitted special char. Non-special chars are OK.
For instance, "à" becomes "a`", and "é" becomes "e´". Did anyone get this kind of trouble?
Here is the code
DirectoryInfo di = new DirectoryInfo(path);
foreach (FileInfo fi in di.GetFiles())
{
Logger.LogInfo("Info: " + fi.Name);
}
Basically, if string is "sàrl", log saved "Info: sa`rl"
When I breakpoint trough VS, I see the string with "à" but when I log it, char are splitted.
My SQL collation is Latin CI AS (SQL_Latin1_General_CP1_CI_AS) and DB already host string with special char without problem.
Thanks folks
EDIT
I have trouble when I insert the fi.Name into the final table too:
public bool InsertFile(string fileName, Societe company, string remark, PersonnelAM creator)
{
string commandText = (#"INSERT INTO [dbo].[TB_DOCSOCIETE_COM] " +
"([IdtSOC] " +
",[NomDOC] " +
",[RemDOC] " +
",[DateDOC] " +
",[IdtPER]) " +
"VALUES " +
"(#company" +
",#fileName" +
",#remark" +
",#date" +
",#creator) SELECT ##IDENTITY");
var identity = CreateCommand(commandText,
new SqlParameter("#fileName", DAOHelper.HandleNullValueAndMinDateTime<string>(fileName)),
new SqlParameter("#company", DAOHelper.HandleNullValueAndMinDateTime<int>(company.Id)),
new SqlParameter("#remark", DAOHelper.HandleNullValueAndMinDateTime<string>(remark)),
new SqlParameter("#date", DAOHelper.HandleNullValueAndMinDateTime<DateTime>(DateTime.Now)),
new SqlParameter("#creator", DAOHelper.HandleNullValueAndMinDateTime<int>(creator.id))
).ExecuteScalar();
return int.Parse(identity.ToString()) > 0;
}
I'm using NLog so data is varchar(8000) for message column and code that logs message is
public static bool LogInfo(Exception ex, string message = "")
{
try
{
GetLogger().Log(LogLevel.Info, ex, message);
}
#pragma warning disable 0168
catch (Exception exception)
#pragma warning restore 0168
{
return false;
}
return true;
}
EDIT 2 :
To be clear about DB, those 3 lines:
Logger.LogInfo("BL1 " + "sàrl is right saved");
Logger.LogInfo("BL2 " + fi.Name + " is not right saved");
Logger.LogInfo("BL3 " + "sàrl" + " - " + fi.Name + " is not right too!");
Gave me that result in DB:
BL1 sàrl is right saved
BL2 ENTERPRISE Sa`rl - file.pdf is not right saved
BL3 sàrl - ENTERPRISE Sa`rl - file.pdf is not right too!
So it doesn't come from DB, it is an issue about the string (encoding?)
varchar(8000)
Make the column NVARCHAR. This is not a collation issue. Collations determine the sort order and comparison rules, not the storage. Is true that for non-unicode columns (varchar) the collation is used as hint to determine the code page of the result. But code page will only get you so far, as obviously a 1 byte encoding code page cannot match the entire space of the file system naming, which is 2 bytes encoding Unicode based.
Use an Unicode column: NVARCHAR.
If you want to understand what are you experiencing, just run this:
declare #a nvarchar(4000) = NCHAR(0x00E0) + N'a' + NCHAR(0x0300)
select #a, cast(#a as varchar);
Unicode is full of wonderful surprises, like Combining characters. You can't distinguish them visually, but they sure show up when you look at the actual encoded bytes.

c# textbox-as-filename problems

I have been trying to make a program and it saves mechanics invoices. So I have got this far;
oWord.Application.ActiveDocument.SaveAs2("C:/BMW/Invoices/" + Regbox.Text + "/thing.doc");
which saves the word doc in a folder that is specified by the registration of the bike - this works fine. but what I really want is the date to be used as a filename...I couldn't figure that out, so I made a date label and plan on using the text from it as the filename instead (I know, its a long way round...but it works). Anyways, I have tried;
oWord.Application.ActiveDocument.SaveAs2("C:/BMW/Invoices/" + Regbox.Text + "/" + label19.Text + ".doc");
this was an "invalid filename"
oWord.Application.ActiveDocument.SaveAs2("C:/BMW/Invoices/" + Regbox.Text + "/label19.Text.doc");
this saved it as "label19.Text.doc"
oWord.Application.ActiveDocument.SaveAs2("C:/BMW/Invoices/" + Regbox.Text + "/" + label19.Text, ".doc");
This threw the error "(DISP_E_TYPEMISMATCH)"
All I need to do is get label19 text to work as a filename with a .doc extension...or another way of getting the date as a filename
If you need to use current date as file name then you can use:
oWord.Application.ActiveDocument.SaveAs2("C:/BMW/Invoices/" + Regbox.Text + "/" + DateTime.Now.ToString("MM-dd-yyyy") + ".doc")
Generate the file name in an string variable:
string filename = "C:/BMW/Invoices/" + Regbox.Text + "/" + DateTime.Now.ToString("MM-dd-yy");
and then pass it to SaveAs2 method:
oWord.Application.ActiveDocument.SaveAs2(filename, ".doc");

Renaming files programmatically, decrementing

I have a folder with a certain number of text files named 1.txt, 2.txt 3.txt etc.
My goal is that when one of them is deleted, to rename any of the files greater than the file deleted down one.
Ex. if 1.txt is deleted, 2 should be renamed to 1, and 3 renamed to 2, so on and so forth.
Here is my attempt so far:
private void deletequestionbtn_Click(object sender, EventArgs e)
{
string fileDel = testfolderdialog.SelectedPath.ToString() + #"\" + questionCountint.ToString() + ".txt";
DirectoryInfo d = new DirectoryInfo(testfolderdialog.SelectedPath.ToString() + #"\");
File.Delete(fileDel);
questionCountint++;
foreach (var file in d.GetFiles("*.txt"))
{
string fn = file.Name;
string use = fn.Replace(".txt", "");
int count = int.Parse(use);
if (count > questionCountint)
{
File.Move(fileDel, testfolderdialog.SelectedPath.ToString() + #"\" + questionCountint--.ToString() + ".txt");
}
}
}
The issue is occuring on the File.Move line, it's saying it cannot locate the file in fileDel, though I am incrementing questionCountint after deleting fileDel
Am I approaching this the wrong way? Is there a more effective way to write the foreach statement? I only want to rename the files greater than the file deleted.
Where am I going wrong?
The problem is that you are trying to rename fileDel, which is the file that you have deleted. You should rename file instead.
However, you will quickly run into the next problem. If you don't get the files in the exact order that you expect, you will try to rename a file to a name that already exists.
If the GetFiles method returns the files in the order "3.txt", "2.txt", you will first try to rename "3.txt" to "2.txt", but "2.txt" already exists.
You should first loop through the files and gather all files that should be renamed. Then you should sort the files on the number so that you can rename them in the correct order.
As the format of the file names is so simple to recreate from the number, you can just get the numbers in a list:
List<int> files = new List<int>();
foreach (var file in d.GetFiles("*.txt")) {
string fn = file.Name;
string use = fn.Replace(".txt", "");
int count = int.Parse(use);
if (count > questionCountint) {
files.Add(count);
}
}
string path = testfolderdialog.SelectedPath.ToString();
foreach (int count in files.Ordery(n => n)) {
File.Move(String.Concat(path, count.ToString() + ".txt"), String.Concat(path, (count - 1).ToString() + ".txt");
}

How to specify a file path in ASP.NET MVC

I want to specify a virtual path of a file but I am not able to do so.
Here is my code:
int Course_Id = 1;
int PortfolioID=1;
int ChandidateID=1;
string filepath = Server.MapPath("~/ePortfolio/PortFolioContent/" + Course_Id + "/Assignments/Exhb_" + item.PortfolioID + "_" + item.ChandidateID + ".jpg");
if(System.IO.File.Exists((filepath)))
{
ViewBag.Thumbnail = filepath;
}
When i use Server.MapPath it is fetching data from some other path:
My original path is:
E:\HOBBYHOMES(E-PORTFOLIO)\HobbyHomesWebApp\ePortfolio\PortFolioContent\1\Assignments
but it is taking this path
E:\HOBBYHOMES(E-PORTFOLIO)\HobbyHomesWebApp\ActivityPostin\Images\ePortfolio\PortFolioContent\1\Assignments\Exhb_1_1.jpg
I m not understanding why this is workin so.Please help me
Try string filepath = Server.MapPath("~/... ...jpg");
You can use #Url.Content("~/Content/Images/YourImageName.png")
Try doing something like this:
Path.Combine(Server.MapPath("~/"),("ePortfolio\\PortFolioContent\\" + Course_Id + "\\Assignments\\Exhb_" + item.PortfolioID + "_" + item.ChandidateID + ".jpg"));
In theory it results in the same answer that failed you previously. In practice, it may yield a completely different answer.
There's also a recent question here (which I can't find at the moment) which highlights that sometimes Server.MapPath("~/..etc..") misbehaves on rewritten request paths. Are you rewriting the request that is trying to form this path?

Categories