Within a SSIS Script Task, I have the below code that checks if a folder is empty. I then want to pass if it is or not into the variable 'Dim_File_Count' and use a Precedence constraint to move onto the next task if successful. However my code keeps stating the folder is empty, even when it's not:
public void Main()
{
//string FolderName = Dts.Variables["User::Tech_Dim"].Value.ToString();
if (File.Exists(Dts.Variables["User::Tech_Dim"].Value.ToString())==false)
{
Dts.Variables["User::Dim_File_Count"].Value = 0;
MessageBox.Show("folder empty");
}
else
{
Dts.Variables["User::Dim_File_Count"].Value = 1;
MessageBox.Show("folder is not empty");
}
Dts.TaskResult = (int)ScriptResults.Success;
}
You can use the Length property of the GetFiles method of the Directory class to check if there are any files in the specified folder. The optional third SearchOption parameter of GetFiles can be used if searching sub-directories is necessary, i.e. SearchOption.AllDirectories, with the default checking only the parent folder.
if (Directory.GetFiles(Dts.Variables["User::Tech_Dim"].Value.ToString(), "*").Length > 0)
{
Dts.Variables["User::Dim_File_Count"].Value = 0;
MessageBox.Show("folder empty");
}
else
{
Dts.Variables["User::Dim_File_Count"].Value = 1;
MessageBox.Show("folder is not empty");
}
Related
I am currently attempting to create a function code that creates a subdirectory inside a user-specific path by having the user input the Directory path and then in main use the Directory.GetDirectories(arwgs) function to get a string array of there path.
This code works for the first attempt but after rerunning it again it creates a folder in same directory in the that I don't want to do again.
Good:
Directorys Created S:\Shop....\600\UnitCalFall
Bad:
Directorys Created S:\Shop\600\UnitCalFall\UnitCalFall
or
Directorys Created S:\Shop\600\UnitCalFall\UnitCalDone
I am trying to make the function as fast and integrative as possible so incase the user wants to create more than one or two folders.
The code is shown below:
static void UnitCalFolderCheck(string[] sDirectoryPath, string[] NewFolder)
{
//possible method can be constructed that checks for if a option UnitCallFolder has been created
for (int index = 0; index < sDirectoryPath.Length; index++)
{
//for each directory in the path if a folder named as UnitCalDONE in order to store CSV files data that has already been stored and conducted.
//ig a foldered labeled as such is already created then do not create this folder
string sCurrentPath = sDirectoryPath[index];
//check if current directory path already is created by the newfolder length path
//NEED TO CREATE A VARIABLE THAT CHECKS IF ANY OF THE SUBSTRINGS ARE TRUE AND IF SO DO NOT CHECK FOR NEW DIRECTORY
bool bexist = false;
//Console.WriteLine(sCurrentPath);
//also check if a the current path also has the UnitCalFolder Done already. This is because the newDirpath
//Will be a duplication of each folder and this can cause problems for the for loop
//append for each dirpath the folder information
for (int i = 0; i < NewFolder.Length; i++)
{
int NewFolderLength = NewFolder[i].Length;
string sNewDirPath = sCurrentPath + NewFolder[i];
string substring = sCurrentPath.Substring(sCurrentPath.Length - NewFolderLength);
//looping around the new possible created folders based on the substring paths
foreach (string x in NewFolder)
{
//THIS DOESNT CHECK IF FOLDER IS DIFFERENT FROM THE OTHER CONTAINER
// Console.WriteLine(x);
if (!substring.Contains(x)) //not working propery
{
bexist = true;
}
else
{
bexist = false;
}
}
if (!Directory.Exists(sNewDirPath) && (bexist == true) )
{
Directory.CreateDirectory(sNewDirPath);
Console.WriteLine("Directorys Created" + sNewDirPath);
}
}
}
}
*A crude way of fixing but when looking back this can work for folders with the suffix "UnitCal". At least for my directory. Not the most elegant but works.
static void UnitCalFolderCheck(string[] sDirectoryPath, string[] NewFolder)
{
//possible method can be constructed that checks for if a option UnitCallFolder has been created
for (int index = 0; index < sDirectoryPath.Length; index++)
{
//for each directory in the path if a folder named as UnitCalDONE in order to store CSV files data that has already been stored and conducted.
//ig a foldered labeled as such is already created then do not create this folder
string sCurrentPath = sDirectoryPath[index];
//Console.WriteLine(sCurrentPath);
//int[] iexist = new int[NewFolder.Count()]; //if substring exist already then dont create new directory
//int inotexist = 0;
string sNewDirPath;
string FolderIndexPath = "";
//for every new folder in the path check if the directory with substring already exist
for(int x = 0; x < NewFolder.Length; x++)
{
int NewFolderLength = NewFolder.Length; //length of the new folder to append to newdirpath string
//string substring = sCurrentPath.Substring(sCurrentPath.Length - NewFolderLength);
//UnitCalDone folder first iteration
//UNitCalFall folder secnond iteration
Console.WriteLine("========================================================================");
Console.WriteLine(sCurrentPath);
Console.WriteLine(NewFolder[x]);
if (!sCurrentPath.Contains("UnitCal"))
{
// iexist[x] = 0;
sNewDirPath = sCurrentPath + NewFolder[x];
// Determine whether the directory exists.
if (!Directory.Exists(sNewDirPath))
{
//check if new path already exist if so then do nothing
Console.WriteLine("NEWPATH->>>");
//Directory.CreateDirectory(sNewDirPath);
Console.WriteLine(sNewDirPath); //check that none of this values contain the selected values
}
}
else
{
//do nothing
}
}
}//end of for loop method
}//end of unitCalFolderCheckr code here*
I'm doing a console project whose goal is to search the entire disk for all files with the extension '.config'
I've tried something like:
foreach (string file in Directory.GetFiles("C:\\", "*.config", SearchOption.AllDirectories))
{
Console.WriteLine(file);
Console.ReadLine();
}
but gave me an error "denied access to path (...)".
On the internet I found this code:
Stack<string> pending = new Stack<string>();
pending.Push("C:\\");
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, "*.config");
}
catch { }
if (next != null && next.Length != 0)
foreach (var file in next)
{
Console.WriteLine(file);
Console.ReadLine();
}
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
but it just shows the path clicking always in 'enter' and I want to save those files/path in a list.
Someone can help?
There are two things you can do to improve that code:
Use Directory.EnumerateFiles() and Directory.EnumerateDirectories() to avoid making a copy of the names of all the files in each directory.
Make the return type of the method IEnumerable<string> to make it easier to consume.
We also need to be very careful about exceptions caused by attempting to access protected files and directories. The code below is also complicated by the fact that you're not allowed to yield return from inside a try/catch block, so we have to rearrange the code somewhat.
(Also note that we have to dispose the enumerator returned from .GetEnumerator(); normally this is done automatically when you use foreach, but in this case we can't - because of having to avoid doing yield return in a try/catch - so we have to use using to dispose it.)
Here's a modification of your original code to do this:
public static IEnumerable<string> GetFiles(string root, string spec)
{
var pending = new Stack<string>(new []{root});
while (pending.Count > 0)
{
var path = pending.Pop();
IEnumerator<string> fileIterator = null;
try
{
fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();
}
catch {}
if (fileIterator != null)
{
using (fileIterator)
{
while (true)
{
try
{
if (!fileIterator.MoveNext()) // Throws if file is not accessible.
break;
}
catch { break; }
yield return fileIterator.Current;
}
}
}
IEnumerator<string> dirIterator = null;
try
{
dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();
}
catch {}
if (dirIterator != null)
{
using (dirIterator)
{
while (true)
{
try
{
if (!dirIterator.MoveNext()) // Throws if directory is not accessible.
break;
}
catch { break; }
pending.Push(dirIterator.Current);
}
}
}
}
}
As an example, here's how you could use a console app to list all the accessible ".txt" files on the "C:\" drive:
static void Main()
{
foreach (var file in GetFiles("C:\\", "*.txt"))
{
Console.WriteLine(file);
}
}
Replace the lines
Console.WriteLine(file);
Console.ReadLine();
with a method to store them in a list.
For example
foundFiles.Add(file);
Then when the method is done, you can read all found file paths from this list.
Notes:
This will not yield all files on the system that match the filter.
Only files where your application has access to their respective directory are found this way.
For example the Windows directory and user directories of other users are usually protected. (assuming you run on Windows)
Keep in mind, that some files might be protected independently of their directory.
So when trying to read them, also consider the fact, that the read might fail.
Just encompass the read with a try catch.
Regarding the error "denied access to path (...)", sometimes you have to run Visual Studio as an a administrator in order to access some folders in the C:\ drive.
In my application the user can enter a filename. Before processing I'd like to check if the input String is a valid filename on Windows Vista.
Whats the easiest way to do that?
By valid I'm reffering to legal and non-existing
Check whether filename.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 and !File.Exists(Path.Combine(someFolder, filename))
Check against GetInvalidFileNameChars():
var isValid = !string.IsNullOrEmpty(fileName) &&
fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
!File.Exists(Path.Combine(sourceFolder, fileName));
If the file is going to be created, You should use a file dialog to specify the directory path. There's a short list of illegal characters for file names.
The only truly reliable way to tell if a file name is acceptable is to try it. Permissions
is a morass.
I use this:
public static bool IsValidFileName(string name) {
if(string.IsNullOrWhiteSpace(name)) return false;
if(name.Length > 1 && name[1] == ':') {
if(name.Length < 4 || name.ToLower()[0] < 'a' || name.ToLower()[0] > 'z' || name[2] != '\\') return false;
name = name.Substring(3);
}
if(name.StartsWith("\\\\")) name = name.Substring(1);
if(name.EndsWith("\\") || !name.Trim().Equals(name) || name.Contains("\\\\") ||
name.IndexOfAny(Path.GetInvalidFileNameChars().Where(x=>x!='\\').ToArray()) >= 0) return false;
return true;
}
Should take care of everything but reserved names, permissions, and length restrictions. This accepts both relative and absolute filenames.
This is just an idea. One should populate the exception list:
public static bool IsValidFilename(string filename)
{
try
{
File.OpenRead(filename).Close();
}
catch (ArgumentException) { return false; }
catch (Exception) { }
return true;
}
For first part(Valid Filename), I use all ways and a temporary file creation to check if a file can be named as expected or throws an exception.
In some cases creating a file will not raise an exception until trying to delete it(eg: CON).
I also usa removePath arg to dictate it that file is just the name of file without its path.
using System.IO;
using System.Text;
private static readonly byte[] TestFileBytes = Encoding.ASCII.GetBytes(#"X");
public bool IsFileNameValid(string file, bool removePath = false)
{
try
{
if (string.IsNullOrEmpty(file))
return false;
string fileNamePart = removePath ? Path.GetFileName(file) : file;
if (fileNamePart.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
return false;
string fileName = Path.Combine(Path.GetTempPath(), fileNamePart);
using FileStream fileStream = File.Create(fileName);
{
fileStream.Write(TestFileBytes, 0, TestFileBytes.Length);
}
File.Delete(fileName);
return true;
}
catch
{
return false;
}
}
If there is any denial of access to temp folder use a custom folder for creating test file.
This method will result false for . or .. or ... r any sequence of dot-only names in Windows, and also you can't create them manually, but those are not actually invalid names! those are uncreatable names for file or something like that ;).
And for next part(Not exists) just use: !File.Exists(yourFileNameWithPath).
If you create a DirectoryInfo for the file, it will throw an exception if there are any problems with the file/directory name, either invalid chars or length.
DirectoryInfo di = new DirectoryInfo(myFileName);
Console.WriteLine("This filename/path could be valid. The folder might not exist yet though.")
if(di.Exists)
Console.WriteLine("This file already exist.")
Not great that it is using exceptions for flow control, but you can be confident that it is right. OTOH, if you already planned to give the calling code an exception, mission accomplished.
This program is supposed to show the path of a directory and the directory if its exists then it should also show the files inside with the following extensions (i.e .doc, .pdf, .jpg, .jpeg) but I'm getting an error
*Index was outside the bounds of the array.
on this line of code
string directoryPath = args[0];
This is the code in the main function
class Program
{
static void Main(string[] args)
{
string directoryPath = args[0];
string[] filesList, filesListTmp;
IFileOperation[] opList = { new FileProcNameAfter10(),
new FileProcEnc(),
new FileProcByExt("jpeg"),
new FileProcByExt("jpg"),
new FileProcByExt("doc"),
new FileProcByExt("pdf"),
new FileProcByExt("djvu")
};
if (Directory.Exists(directoryPath))
{
filesList = Directory.GetFiles(directoryPath);
while (true)
{
Thread.Sleep(500);
filesListTmp = Directory.GetFiles(directoryPath);
foreach (var elem in Enumerable.Except<string>(filesListTmp, filesList))
{
Console.WriteLine(elem);
foreach (var op in opList)
{
if (op.Accept(elem)) op.Process(elem);
}
}
filesList = filesListTmp;
if (Console.KeyAvailable == true && Console.ReadKey(true).Key == ConsoleKey.Escape) break;
}
}
else
{
Console.WriteLine("There is no such directory.");
}
}
}
How can I handle this error it seems to be common but it happens id different ways
You need to pass the necessary arguments to the program when running it. You can either do this by running the program from the command line, or else when running Visual Studio by doing the following:
Right click on project
Properties
Debug tag
Enter arguments under Start Options -> Command line arguments
You might want to pass the arguments into the program from command line.
like this:
> yourProgram.exe directoryName
Also, to avoid such problems in the code,
if(args.Length > 0){
string directoryPath = args[0];
}else{
//print a help message and exit, or do something like set the
//default directoryPath to current directory
}
Do you want the user to enter a path when the program starts or when they start the program? If it's the first, then you should add a Console.Read() method that asks for the path.
If it's the latter, then you need to pass the path as an argument when starting the program. You should also do a check against the args array before reading from it to check that it contains data and that data is a valid path.
Something like:
if(args.Length > 0 && Directory.Exists(args[0]))
{
// Do Something.
}
there are nothing is inside my test002 folder, by right my output should be is "nothing is inside the folder",but after compile there are nothing prompt.
what i want to do is if there are any .doc file is inside my folder, just upload it
if there are nothing is inside the folder, ask user to upload .doc to required folder.
protected void Button3_Click(object sender, EventArgs e)
{
try
{
string[] chkUserResume = Directory.GetFiles(HttpContext.Current.Server.MapPath(#"~/Enduser/test002/"), "*.doc");
if (chkUserResume!=null)
{
foreach (string name in chkUserResume)
{
Response.Write(name + " is exist");
}
}
else
{
Response.Write("nothing is inside the folder");
}
}
catch (Exception ex)
{
Response.Write(ex.Message.ToString());
}
}
The null keyword means that the variable is not set to any real value, which is different from an empty array.
In this case, chkUserResume will never be null, it will be an empty array. You should check that chkUserResume.Length is 0 instead.
You're not checking that chkUserResume is empty:
if (chkUserResume.Length == 0)
{
Response.Write("nothing is inside the folder");
}
else
{
foreach (string name in chkUserResume)
{
Response.Write(name + " is exist");
}
}
However as chkUserResume will never be null there's no need to check for that.