Rename file 20181207_ProdAndPressuresExport.csv to ProdAndPressuresExport.csv - c#

I have the following C# code but having issues renaming the file to what I want (ProdAndPressuresExport.csv). It is renaming the file as ProdAndPressuresExportProdAndPressuresExport.csv and also moving the rename file up 1 folder. I would like for it to stay in its original file path C:\TEMP\CSVFile\ProdAndPressuresExport. Please help.
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
const string DIRECTORY_PATH = #"C:\TEMP\CSVFile\ProdAndPressuresExport";
const string FILE_NAME_TEMPLATE = "*_ProdAndPressuresExport.CSV";
if (Directory.Exists(DIRECTORY_PATH))
{
string[] filePathList = Directory.GetFiles(DIRECTORY_PATH, FILE_NAME_TEMPLATE);
foreach (string filePath in filePathList)
{
if (File.Exists(filePath))
{
string newName = DIRECTORY_PATH + filePath.Split('_')[1];
File.Move(filePath, newName);
}
}
}
}
}
}

Always use Path.Combine to construct paths, rather than string concatenation.
string newName = DIRECTORY_PATH + filePath.Split('_')[1];
Should be
string newName = Path.Combine(DIRECTORY_PATH, filePath.Split('_')[1]);
Otherwise you miss the directory separator character, and your file will end up in the parent folder above your intended folder with an unintentionally concatenated name.

Related

Restrict my code to write to a specific folder C#

I got a folder in C called "donotcopy". I want to protect it and no matter what not to be allowed to create files within.
My intuitive solution was just to create a str with same name and where user enters a destination it just checks if it's the same.
Example:
class FileCreation
{
public static void Main()
{
string notallowed = ("c:\\donotcopy");
string filename = ("Nick.txt");
Console.WriteLine("Enter the full path to create an empty file.");
string path = Console.ReadLine();
path = path.ToLower();
while (notallowed == path)
{
Console.WriteLine("The chosen path is not allowed please try another one.");
path = Console.ReadLine();
path = path.ToLower();
}
using (FileStream fs = File.Create(path + filename)) ;
}
}
The problem is if the user enters the destination as "c:.\donotcopy" it will still create the file inside the restricted folder.
You can make use of the DirectoryInfo class, which will allow you to retrieve info about the full path of a directory.
class FileCreation
{
public static void Main()
{
string notallowed = ("c:\\donotcopy");
string filename = ("Nick.txt");
Console.WriteLine("Enter the full path to create an empty file.");
DirectoryInfo directory = new DirectoryInfo(Console.ReadLine());
while (notallowed.Equals(directory.FullName, StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("The chosen path is not allowed please try another one.");
directory = new DirectoryInfo(Console.ReadLine());
}
string fullPath = Path.Combine(directory.FullName, filename);
using (FileStream fs = File.Create(fullPath)) ;
}
}

(Updated) Working with files, check if exists or not

I am working with files on C# and I got to a point where I don't know how to continue anymore.
The scenario is this: If I upload 3 or more files with the same name at the same time, I want to handle them and change their name to from "myfile.pdf" to "myfile.pdf(1)/(2)/(3)..." depending on how much files I upload.
This is what I have tried so far and in this case, this only works for only the second file because when the third one comes, it will check there is any file with the same - yes, okay name it "myfile.pdf(2) - but this exists too so it will go to another place.
How can I achieve having the same three files in the same folder with this naming convention?
Here's what I have tried so far:
string FileName = "MyFile.pdf";
string path = #"C:\Project\MyPdfFiles\"
if (File.Exists(path))
{
int i = 1;
var FileExists = false;
while (FileExists==false)
{
if (FileExists == false)
{
FileName = FileName + "(" + i + ")";
}
else
return;
i++;
}
}
And the result of this code is: "MyFile.pdf", "MyFile.pdf(1)" And the third one doesn't load here.
I think I'm missing something in the loop or idk :(.
Can someone help me?
I have tried also this:
if(File.Exists(path) || File.Exists(path+"(")
//because when the second file its uploaded, its name will be SecondFile.pdf(1), so this will return true and will proceed running, but still the iteration will "always" start from 0 since everytime I upload a file, I have to refresh the process.
Don't use return inside your while loop, better set 'FileExists = true' whenever you want you loop to stop. A return statement will exit your current method.
I think your problem can be easily solved using recursion, something like this (untested):
public class Program
{
public string FileName { get; set; }
public Program() {
string fileName = "MyFile.pdf";
string path = #"C:\Project\MyPdfFiles\";
FileName = CheckFileName(path, fileName);
}
public string CheckFileName(string path, string fileName, int iteration = 0) {
if (File.Exists($"{path}{fileName}")) {
iteration++;
CheckFileName(path, $"{fileName}({iteration})", iteration);
}
return fileName;
}
}
What this does is: it CheckFileName method will keep calling itself until it finds a name that doesn't exist yet.
This should do the job.
public class Program
{
public static string GetUnusedFilePath(string directorypath, string filename, string ext)
{
string fullPath = $"{directorypath}{filename}{ext}";
int inc = 0;
// check until you have a filepath that doesn't exist
while (File.Exists(fullPath))
{
fullPath = $"{directorypath}{filename}{inc}{ext}";
inc++;
}
return fullPath;
}
public static void UploadFile(string filepath)
{
using (FileStream fs = File.Create(filepath))
{
// Add some text to file
Byte[] title = new UTF8Encoding(true).GetBytes("New Text File");
fs.Write(title, 0, title.Length);
}
}
public static void Main()
{
string[] filestoUpload = { "file", "file", "file", "anotherfile", "anotherfile", "anotherfile" };
string directorypath = #"D:\temp\";
string ext = ".txt";
foreach(var file in filestoUpload)
{
var filePath = GetUnusedFilePath(directorypath, file, ext);
UploadFile(filePath);
}
}
}
I solved this by creating new folders with special names using the code below:
DirectoryInfo hdDirectoryInWhichToSearch = new DirectoryInfo(FileDirectory);
FileSystemInfo[] filesAndDirs = hdDirectoryInWhichToSearch.GetFileSystemInfos("*" + FullFileName + "*");
int i = filesAndDirs.Length;
if (i>1)
{
FileName = Filename + "(" + i ")";
}
So what this does is that it will count how many files we have in that folder with the same name, so I have to check if we have more than 1 file, then change it's name to file(1).
Thank you to everyone that tried to help me, much appreciated.

Concatenating folder names to file name and copy file to a folde

My folder structure is as .. temp\2016\09\11\16
In the last folder I have multiple text/json files.
I would like to run a console application that would loop through every folder and rename the files with foldernames concatenated.
So a file abcd.json would become 2016091116_abcd.json
Then copy this file to another folder.
I tried..
using System;
using System.IO;
using System.Collections;
namespace concatdf
{
class Program
{
static void Main(string[] args)
{
string folderPath = "D:\\500GBNP\\Projects\\temp";
DirectoryInfo startDir = new DirectoryInfo(folderPath);
RecurseFileStructure recurseFileStructure = new RecurseFileStructure();
recurseFileStructure.TraverseDirectory(startDir);
}
public class RecurseFileStructure
{
public void TraverseDirectory(DirectoryInfo directoryInfo)
{
var subdirectories = directoryInfo.EnumerateDirectories();
foreach (var subdirectory in subdirectories)
{
TraverseDirectory(subdirectory);
}
var files = directoryInfo.EnumerateFiles();
foreach (var file in files)
{
HandleFile(file);
}
}
void HandleFile(FileInfo file)
{
string destfolderPath = "D:\\500GBNP\\Projects\\temp1\\";
file.CopyTo(destfolderPath+file.Name);
}
}
}
}
With the above code I'm able to traverse and copy all files to target directory but file names do not get concatenated with foldernames.
So a file abcd.json in folder temp\2016\09\11\16 would become 2016091116_abcd.json and all files get copied to temp1 folder.
I would sincerely appreciate if someone could help.
You can append the folder name in each recursion and append the destination filename.
using System;
using System.IO;
using System.Collections;
namespace concatdf
{
class Program
{
static void Main(string[] args)
{
string folderPath = "D:\\500GBNP\\Projects\\temp";
DirectoryInfo startDir = new DirectoryInfo(folderPath);
RecurseFileStructure recurseFileStructure = new RecurseFileStructure();
recurseFileStructure.TraverseDirectory(startDir, string.Empty);
}
public class RecurseFileStructure
{
public void TraverseDirectory(DirectoryInfo directoryInfo, string fileAppend)
{
var subdirectories = directoryInfo.EnumerateDirectories();
foreach (var subdirectory in subdirectories)
{
TraverseDirectory(subdirectory, fileAppend + subdirectory.Name);
}
var files = directoryInfo.EnumerateFiles();
foreach (var file in files)
{
HandleFile(file, fileAppend);
}
}
void HandleFile(FileInfo file, string fileAppend)
{
string destfolderPath = "D:\\500GBNP\\Projects\\temp1\\";
file.CopyTo(destfolderPath + fileAppend +"_"+ file.Name);
}
}
}
}
We just need to make HandleFile a bit more intelligent. Let's take the last 4 folder names and add it to the name..
void HandleFile(FileInfo file)
{
string destfolderPath = "D:\\500GBNP\\Projects\\temp1\\";
var pathBits = file.DirectoryName.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var s = string.Concat(pathBits[^4..]);
file.CopyTo(Path.Combine(destfolderPath, s+'_'+file.Name));
}
This renames the file as it copies (which seemed a more sensible way to go, to me). If you truly want to rename the file before you copy, insert a call to FileInfo.MoveTo() after you copy
Strive to use Path when working with paths, not string concatenation
What about something simpler like this?:
public static void CopyFiles(DirectoryInfo sourceDirectory, DirectoryInfo targetDirectory)
{
// This will provide all files in sourceDirectory and nested directories
foreach (var file in sourceDirectory.EnumerateFiles("*", SearchOption.AllDirectories))
{
// work out what the relative path from sourceDirectory is
// e.g. 2016\09\11\16\abcd.json
string relativePath = Path.GetRelativePath(sourceDirectory.FullName, file.FullName);
// get the directory part and replace the separator with an empty string (this could be
// made more efficient)
string directoryPart = Path.GetDirectoryName(relativePath)
.Replace(Path.DirectorySeparatorChar.ToString(), string.Empty);
// get just the filename
string filePart = Path.GetFileName(relativePath);
// combine the target directory, the directory part, and the filename part
// I've made the assumption that you don't want files in the base directory
// to be called _filename, so we just use filePart when there is no directoryPart
string newFileName = string.IsNullOrEmpty(directoryPart) ? filePart : $"{directoryPart}_{filePart}";
string newFullName = Path.Combine(targetDirectory.FullName, newFileName);
// copy the file to the new location
file.CopyTo(newFullName);
}
}

Why is File.Move not working as expected?

I am trying to move all files from rootFolderPath to destinationPath
try
{
string rootFolderPath = #"D:\Log_siteq\";
if (!Directory.Exists(Path.Combine(#"D:\Log_takaya\" + comboBox1.SelectedItem.ToString())))
{
System.IO.Directory.CreateDirectory(Path.Combine(#"D:\Log_takaya\" + comboBox1.SelectedItem.ToString()));
}
string destinationPath = Path.Combine(#"D:\Log_takaya\" + comboBox1.SelectedItem.ToString() );
string fileTypes = #"*.*";
string[] fileList = System.IO.Directory.GetFiles(rootFolderPath, fileTypes);
foreach (string file in fileList)
{
string ext = Path.GetExtension(file);
string destination = Path.Combine(destinationPath,file);
File.Move( file,destination);
MessageBox.Show(file);
MessageBox.Show(destination);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
Apparently MessageBox.Show(file); shows me my root folder path ( as is normal) but MessageBox.Show(destination); is showing me the same thing.
What gives? It just moves my file from my root folder in the same folder.Am I not getting something?
You are combining the destinationPath with the complete file path of file:
string destination = Path.Combine(destinationPath, file);
which will just overwrite the destination with the original file path (because "C:\desitnation\C:\source\filename.txt" isn't a valid path).
Instead, you need only the file name like this:
string destination = Path.Combine(destinationPath, Path.GetFileName(file));

how to parse multiple file names and get relevant information in C# asp aspx

I've been trying to figure out a way for the program to read all of the files from the path or zip file as input. Than read all of the file names inside of the input folder and split it so I can get information such as what is product id and chip name. Than store the pdf file in the correct db that matches with the product id and chip name.
The product id would be KHSA1234C and chip name LK454154.
Example File name: N3405-H-KAD_K-KHSA1234C-542164143_LK454154_GFK.pdf
public void btnUploadAttach_Click(object sender, EventArgs e)
{
string fName = this.FileUploadCFC.FileName;
string path = #"C:\mydir\";
string result;
result = Path.GetFileNameWithoutExtension(fName);
Console.WriteLine("GetFileNameWithoutExtension('{0}') return '{1}'",
fName, result);
result = Path.GetFileName(path);
Console.WriteLine("GetFileName('{0}') return '{1}'", path, result);
string[] sSplitFileName = fName.ToUpper().Split("-".ToCharArray());
foreach (char file in fName)
{
try
{
result = sSplitFileName[0] + "_" + sSplitFileName[1] + "-" +
sSplitFileName[2] + "_" + sSplitFileName[3] + "_" +
sSplitFileName[4] + "_" + sSplitFileName[5] + "_" +
sSplitFileName[6];
}
catch
{
return;
}
}
}
I don't know if I'm on the right track or not.
Can someone help me? Thank you.
first of all, in order to read all files in a folder you should use Directory.GetFiles, then you will iterate through this folder's files. Then you split file name's.. here you go..
using System.IO;
..
..
..
static void Main(string[] args)
{
string[] filePaths = Directory.GetFiles(#"c:\", "*.pdf");
string result;
foreach (var file in filePaths)
{
result = Path.GetFileNameWithoutExtension(file);
Console.WriteLine("GetFileNameWithoutExtension('{0}') return '{1}'",
file, result);
var sSplitFileName = file.ToUpper().Split('-');
var i = 0;
foreach (var item in sSplitFileName)
{
if (i == 3)
//it is product id
if (i == 7)
//it is chip name
i++;
}
}
}
To make a affirmative statement: You are on the right track - but not there yet :-)
First you need to read the files from your path, you don't do this currently.
Directory.GetFiles() may be the thing to search for. This will return a list of filenames as string[] array.
The you need to iterate over the files and apply the splitting, which looks ok to me in your code.
When you have the parts of your file, you want to decide on the database to use. It may be wise to split the filename your own filename class, that exposes properties for each part of the filename, but this is not required.
Next you need to get the db programming right, there are numerous examples on how to do this. Good luck :-)
Assuming the files all follow the same pattern you can probably just split on all of the deliminator characters '-' and '_'.
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(#"C:\mydir\", "*.pdf");
foreach (var file in files)
{
var fileName = Path.GetFileNameWithoutExtension(file);
var tokens = fileName.Split('-', '_');
for(int i=0;i<tokens.Length;i++)
{
string token = tokens[i];
Console.WriteLine("{0}-{1}", i, token);
}
Console.WriteLine();
}
Console.ReadLine();
}
}

Categories

Resources