I want to transfer txt and sql extentions files in their spesific folders. In the below method first createdirectory works well but second gives an IOException error and says me there is already a folder with same name.
What do I miss ?
private void InstallProgram()
{
string _sql = "sql";
string _txt = "txt";
DirectoryInfo d = new DirectoryInfo(executpath);
string destdir = Path.Combine(executpath,_sql);
Directory.CreateDirectory(destdir); // This works
string[] filebox = Directory.GetFiles(executpath, "*." + _sql);
foreach(var item in filebox)
File.Move(item,Path.Combine(destdir,Path.GetFileName(item)));
destdir = Path.Combine(executpath, _txt);
Directory.CreateDirectory(destdir); // Where I get the error
filebox = Directory.GetFiles(executpath, "*." + _txt);
foreach (var item in filebox)
File.Move(item,Path.Combine(destdir,Path.GetFileName(item)));
}
Related
I am making an app in C# where I am searching if the file exists in the text file or not. If it does not exist then, it would add it in the text file and then append it in a List. But, for some reason the list only takes one file and ends at that point. So, can someone help me with what is the problem in this foreach loop?
static void CheckNewFile()
{
string path_f = #"File_Address_where_Text_file_exists";
var new_file = new List<string>();
if (!File.Exists(path_f)) # Checking if the text file exists or not and then creating it
{
var myFile = File.Create(path_f);
myFile.Close();
}
DirectoryInfo hdDirectoryInWhichToSearch = new DirectoryInfo(#"File_Address_in_which_Files_need_to_be_searched");
FileInfo[] filesInDir = hdDirectoryInWhichToSearch.GetFiles("AC" + "*" + "*.*" + "AC"); # Format of the file to be searched
foreach (FileInfo foundFile in filesInDir) # foreach for the files in the directory
{
string fullName = foundFile.FullName;
int flag = 0;
var lines = File.ReadLines(path_f);
foreach (var line in lines) # Reading line by line and checking if the file exists in the text file before
{
if (String.Equals(line, fullName))
{
flag += 1;
break;
}
}
if (flag < 1)
{
if (new FileInfo(path_f).Length == 0) # File Address is appended in the File
{
//TextWriter tw = new StreamWriter(path_f);
//tw.WriteLine(fullName);
//tw.Close();
}
else
{
//using (var tw = new StreamWriter(path_f, true))
//{
// tw.WriteLine(fullName);
//}
}
new_file.Add(fullName.ToString()); # Adding File Address to the list
flag = 0;
break;
}
}
}
Remove the last break. It is causing the program flow to leave the enclosing foreach loop with the file names.
As the other poster mentioned, you're breaking out of your loop early in the if block.
However, there isn't really a need for the flag (or loop or if block) at all. Your method could be simplified greatly by using a little System.Linq and just using Directory to find the new files by comparing their paths to the contents of the input file.
For example:
static List<string> CheckForNewFiles(string filePath, string searchDir,
string searchPattern)
{
// Create file if it doesn't exist
if (!File.Exists(filePath)) using (File.Create(filePath)) ;
// Get list of files that match search pattern which aren't contained in our file
var newFiles = Directory
.GetFiles(searchDir, searchPattern)
.Where(match => !File.ReadLines(filePath).Contains(match))
.ToList();
// Add the new file paths to our file
File.AppendAllLines(filePath, newFiles);
// Return the list of new files (?)
return newFiles;
}
In use it migth look something like:
public static void Main()
{
Console.WriteLine("Checking for new files...");
var newFiles = CheckForNewFiles(#"c:\temp\paths.txt", #"c:\temp\temp", "*.png");
Console.WriteLine($"{newFiles.Count} files found since last search.");
if (newFiles.Any())
{
Console.WriteLine(" -> " + string.Join(Environment.NewLine + " -> ", newFiles));
}
Console.ReadLine();
}
I have a field in a table that needs to be filled with the path and the end of the XML file to create a new file in the directory called DONE. This is made so it can tidy the directory a bit since the ones that are done don't need to be in the same directory so they are copied from one place into another.
Why is there this error?
System.NotSupportedException: 'The specified path format is not supported.'
Console.WriteLine("Ficheiro processado: " + filename);
string rootFolderPath = #"C:\XMLFiles";
string destinationPath = #"C:\XMLFiles\DONE";
string[] fileList = Directory.GetFiles(rootFolderPath);
foreach (string file1 in fileList)
{
string fileToMove = rootFolderPath + file1;
string moveTo = destinationPath + file1;
File.Move(fileToMove, moveTo);
da.SP_Insert(filename, file.Name, batch.BatchClassName, batch.Name, batch.Description, 0, "", 1, moveTo );
}
The function Directory.GetFiles(rootFolderPath); returns the full path to the file, that is filename and directory. If, like you are trying, want the filename only, you will need to extract it.
The FileInfo class is very good at extracting the Filename only of a full path.
foreach (string file1 in fileList)
{
FileInfo fi = new FileInfo(file1);
string moveTo = Path.Combine( destinationPath, fi.Name);
File.Move(file1, moveTo);
}
Rather than using string fileToMove = rootFolderPath + file1, try using System.IO.Path.Combine instead:
var fileToMove = Path.Combine(rootFolderPath, file1);
var moveTo = Path.Combine(destinationPath , file1);
GetFiles returns full paths; not just filenames:
Returns the names of files (including their paths) in the specified directory
So for the source files you don't need to combine anything, and for the target path you need to split off the filename first before combining:
foreach (string file1 in fileList)
{
string moveTo = Path.Combine(destinationPath, Path.GetFileName(file1));
File.Move(file1, moveTo);
// ...
}
This Problem was fixed this way.
using (OpenFileDialog openFileDialog1 = new OpenFileDialog())
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string CaminhoInicial = openFileDialog1.FileName;
Guid g = Guid.NewGuid();
FileInfo fi = new FileInfo(CaminhoInicial);
File.Copy(CaminhoInicial, CaminhoFinal + g.ToString() + fi.Extension, true);
da.SP_Inserir_Imagem(id, g.ToString() + fi.Extension);
}
}
try
{
if (dt.Rows.Count != 0)
{
string NomeImagem = dt.Rows[0][0].ToString();
pictureBox1.Image = Image.FromFile(CaminhoFinal + NomeImagem.Replace(" ", ""));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + " |||| " + ex.StackTrace, "Erro", MessageBoxButtons.OK);
}
Also read this Microfost Docs post for more context.
https://learn.microsoft.com/en-us/dotnet/api/system.io.fileinfo?view=net-5.0
I have following List<String> fileNames getting passed to my method,
I want to remove the sub-path from that and create the left out file structure
string subPath = "C:\\temp\\test"
List<string> filesIncoming = new List[]{#"C:\temp\test\a.txt", #"C:\temp\test\intest\a.txt"};
string outputDir = "C:\\temp3\\temp";
Output should be:
C:\\temp3\temp\a.txt
C:\\temp3\temp\intest\a.txt
This is what I am trying
foreach (var file in files)
{
var directory = Path.GetDirectoryName(file);
DirectoryInfo source = new DirectoryInfo(directory);
var fileName = Path.GetFileName(file);
var destDir = Path.Combine(destinatonFilePath, source.Name); //how do I remove sub-path from source.Name and combine the paths properly?
CreateDirectory(new DirectoryInfo(destDir));
File.Copy(file, Path.Combine(destDir, fileName), true);
}
I think you should use the old good string.Replace to remove the common base path from your incoming files and replace it with the common base path for the output files
string subPath = "C:\\temp\\test"
string outputDir = "C:\\temp3\\temp";
foreach (var file in files)
{
// Not sure how do you have named these two variables.
string newFilePath = file.Replace(subPath, outputDir);
Directory.CreateDirectory(Path.GetDirectoryName(newFilePath));
File.Copy(file, newFilePath, true);
}
there are in the files of my listbox ı want copy files these specified path for example c:\ or any path but error be (value cannot be null parameter name path) error how ı can copy specified path ı wirte this code
string source, fileToCopy, target;
string sourcefolder1;
string destinationfolder;
DirectoryInfo di = new DirectoryInfo(destinationfolder);
FileInfo[] annfiles;
foreach (string s in listBox1.Items)
{
fileToCopy = s;
source = Path.Combine(sourcefolder1, fileToCopy);
target = Path.Combine(destinationfolder, fileToCopy);
File.Copy(source, target);
annFiles = di.GetFiles();
}
I think the problem is here:
string destinationfolder;
You declare an empty string and after try to get DirectoryInfo from what? And Empty string? This thrown an Exception. You can see your code like this:
DirectoryInfo di = new DirectoryInfo("");
This code throw always an Exception.
The question is: what you need in "destinationFolder" parameter?
This is a sample file copy:
string sourceFolder = #"C:\Documents";
string destinationFolder = "#"C:\MyDocumentsCopy";
DirectoryInfo directory = new DirectoryInfo(sourceFolder);
FileInfo[] files = directory.GetFiles();
foreach(var file in files)
{
string destinationPath = Path.Combine(destinationFolder, file.Name);
File.Copy(file.Fullname, destinationPath);
}
string path = "C:\folder1\folder2\file.txt";
What objects or methods could I use that would give me the result folder2?
I would probably use something like:
string path = "C:/folder1/folder2/file.txt";
string lastFolderName = Path.GetFileName( Path.GetDirectoryName( path ) );
The inner call to GetDirectoryName will return the full path, while the outer call to GetFileName() will return the last path component - which will be the folder name.
This approach works whether or not the path actually exists. This approach, does however, rely on the path initially ending in a filename. If it's unknown whether the path ends in a filename or folder name - then it requires that you check the actual path to see if a file/folder exists at the location first. In that case, Dan Dimitru's answer may be more appropriate.
Try this:
string filename = #"C:/folder1/folder2/file.txt";
string FolderName = new DirectoryInfo(System.IO.Path.GetDirectoryName(filename)).Name;
Simple & clean. Only uses System.IO.FileSystem - works like a charm:
string path = "C:/folder1/folder2/file.txt";
string folder = new DirectoryInfo(path).Name;
DirectoryInfo does the job to strip directory name
string my_path = #"C:\Windows\System32";
DirectoryInfo dir_info = new DirectoryInfo(my_path);
string directory = dir_info.Name; // System32
I used this code snippet to get the directory for a path when no filename is in the path:
for example "c:\tmp\test\visual";
string dir = #"c:\tmp\test\visual";
Console.WriteLine(dir.Replace(Path.GetDirectoryName(dir) + Path.DirectorySeparatorChar, ""));
Output:
visual
string Folder = Directory.GetParent(path).Name;
var fullPath = #"C:\folder1\folder2\file.txt";
var lastDirectory = Path.GetDirectoryName(fullPath).Split('\\').LastOrDefault();
It's also important to note that while getting a list of directory names in a loop, the DirectoryInfo class gets initialized once thus allowing only first-time call. In order to bypass this limitation, ensure you use variables within your loop to store any individual directory's name.
For example, this sample code loops through a list of directories within any parent directory while adding each found directory-name inside a List of string type:
[C#]
string[] parentDirectory = Directory.GetDirectories("/yourpath");
List<string> directories = new List<string>();
foreach (var directory in parentDirectory)
{
// Notice I've created a DirectoryInfo variable.
DirectoryInfo dirInfo = new DirectoryInfo(directory);
// And likewise a name variable for storing the name.
// If this is not added, only the first directory will
// be captured in the loop; the rest won't.
string name = dirInfo.Name;
// Finally we add the directory name to our defined List.
directories.Add(name);
}
[VB.NET]
Dim parentDirectory() As String = Directory.GetDirectories("/yourpath")
Dim directories As New List(Of String)()
For Each directory In parentDirectory
' Notice I've created a DirectoryInfo variable.
Dim dirInfo As New DirectoryInfo(directory)
' And likewise a name variable for storing the name.
' If this is not added, only the first directory will
' be captured in the loop; the rest won't.
Dim name As String = dirInfo.Name
' Finally we add the directory name to our defined List.
directories.Add(name)
Next directory
Below code helps to get folder name only
public ObservableCollection items = new ObservableCollection();
try
{
string[] folderPaths = Directory.GetDirectories(stemp);
items.Clear();
foreach (string s in folderPaths)
{
items.Add(new gridItems { foldername = s.Remove(0, s.LastIndexOf('\\') + 1), folderpath = s });
}
}
catch (Exception a)
{
}
public class gridItems
{
public string foldername { get; set; }
public string folderpath { get; set; }
}
An alternative can be to split the path and get the 2nd last element from the path using Index Struct introduced in C# 8.0.
var path = #"C:\folder1\folder2\file.txt";
var folder = path.Split(#"\")[^2]; // 2nd element from the end
Console.WriteLine(folder); // folder2
I don't know why anyone, did not highlight this solution:
string path = "C:/folder1/folder2/file.txt";
string folder = new DirectoryInfo(path).Parent.Name;
Output: folder2
This is ugly but avoids allocations:
private static string GetFolderName(string path)
{
var end = -1;
for (var i = path.Length; --i >= 0;)
{
var ch = path[i];
if (ch == System.IO.Path.DirectorySeparatorChar ||
ch == System.IO.Path.AltDirectorySeparatorChar ||
ch == System.IO.Path.VolumeSeparatorChar)
{
if (end > 0)
{
return path.Substring(i + 1, end - i - 1);
}
end = i;
}
}
if (end > 0)
{
return path.Substring(0, end);
}
return path;
}