Put checkedlistbox items in an array - c#

Adding the items in a checkedListBox:
DirectoryInfo dinfo = new DirectoryInfo(#"D:\\templates");
FileInfo[] Files = dinfo.GetFiles("*.xml");
foreach (FileInfo file in Files)
{
checkedListBox1.Items.Add(file.Name);
}
foreach (string i in checkedListBox1.CheckedItems)
{
string[] array1 = i;
for (int k = 0; k < array1.Length; k++)
{
XmlDocument xdoc1 = new XmlDocument();
xdoc1.Load(array1[k]);
string s1 = array1[k].ToUpper();
int n = s1.IndexOf(array1[k]);
name1 = array1[k].Substring(n);
}
When I'm putting it in an array, with (string[] array1 = i;)
it's an giving error:
Cannot implicitly convert type 'string' to 'string[]' "
any suggestions?

You can not do that. You will need to do something like this
string[] array1 = new string[] { i };
You are trying to assign string to string[]. Which is not allowed.

string[] array1 = new string[]{i};
DirectoryInfo dinfo = new DirectoryInfo(#"D:\\templates");
FileInfo[] Files = dinfo.GetFiles("*.xml");
Array.ForEach(Files, str => checkedListBox1.Items.Add(str.Name));
foreach (string i in checkedListBox1.CheckedItems)
{
XmlDocument xdoc1 = new XmlDocument();
xdoc1.Load(i);
name1 = i.Substring(i.ToUpper().IndexOf(i));
}

Related

Collection was modified; command separated string into list

I have a comma separate string to pass, to be able to get the file to a directory, Below is the code. This error is shown when using string split then convert into the list. can you tell me what part of the error is in my code?
sample value:
StudentList ="Image01.jpg,Image02.jpg"
public FileResult DownloadZipFile(string StudentList)
{
var fileName = string.Format("{0}_ImageFiles.zip", DateTime.Today.Date.ToString("dd-MM-yyyy") + "_1");
var tempOutPutPath = Server.MapPath(Url.Content("~/Assets/Student_ID")) + fileName;
using (ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(tempOutPutPath)))
{
s.SetLevel(9);
byte[] buffer = new byte[4096];
List<string> stringList = StudentList.Split(',').ToList();
foreach (string str in stringList)
{
stringList.Add(Server.MapPath("~/Assets/Student_ID/" + str));
}
for (int i = 0; i < stringList.Count; i++)
{
ZipEntry entry = new ZipEntry(Path.GetFileName(stringList[i]));
entry.DateTime = DateTime.Now;
entry.IsUnicodeText = true;
s.PutNextEntry(entry);
using (FileStream fs = System.IO.File.OpenRead(stringList[i]))
{
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}
s.Finish();
s.Flush();
s.Close();
}
byte[] finalResult = System.IO.File.ReadAllBytes(tempOutPutPath);
if (System.IO.File.Exists(tempOutPutPath))
System.IO.File.Delete(tempOutPutPath);
if (finalResult == null || !finalResult.Any())
throw new Exception(String.Format("No Files found with Image"));
return File(finalResult, "application/zip", fileName);
}
The problem is in your foreach loop. You iterate through the list, but while doing so, you modify the collection. Thats causing the error. One solution to solve this, is to create a temporary dummy List:
List<string> stringList = StudentList.Split(',').ToList();
List<string> tempList = new List<string>();
foreach (string str in stringList)
{
tempList .Add(Server.MapPath("~/Assets/Student_ID/" + str));
}
stringList = tempList;
An alternative solution without a second list, would be to use a classic for-loop:
List<string> stringList = StudentList.Split(',').ToList();
for(int i = 0; i < stringList.Count; i++)
{
stringList [i] = "~/Assets/Student_ID/" + stringList [i];
}

How to convert FileInfo to FileInfo[] on string[]?

I resolved my problem. But error when I was create constructor LI variable is ListViewItem but I can use this in foreach loop?.
ListViewItem LISTA = default(ListViewItem);
foreach (LISTA in this.lstImgAdded.SelectedItems) {
I'm trying to get Length of the list file with my code:
string[] filePaths = (string[])e.Data.GetData(DataFormats.FileDrop, false);
List<FileInfo> fileInfos = new List<FileInfo>();
foreach (string filePath in filePaths)
{
FileInfo f = new FileInfo(filePaths);
fileInfos.Add(f);
This show error like this:
Cannot convert from 'string[]' to 'string'
You cannot convert a class to its exactly identical array of that class. Just use: FileInfo f = new FileInfo(filePath); for your foreach instead
Also, to get the "length of the list of file" will be identical to filePaths.Length
If you need the length, use filePaths.Length instead.
If you want to populate the FileInfo, do this instead:
string[] filePaths = (string[])e.Data.GetData(DataFormats.FileDrop, false);
List<FileInfo> fileInfos = new List<FileInfo>();
foreach (string filePath in filePaths)
{
FileInfo f = new FileInfo(filePaths);
fileInfos.Add(f);
//long s1 = f.Length;
}
And all your file infos will be in the fileInfos and if you need the amount of item in the list, do it by Count like this: fileInfos.Count
Just change filePaths to filePath in the foreach loop
FileInfo f = new FileInfo(filePath);
An alternative would be change the loop like this:
foreach (int s1 in filePaths.Select(filePath => new FileInfo(filePath)).Select(f => ((FileInfo[]) f).Length))
{
//Do somthing with the s1 here
}

Excluded several extension c#

How can I exclude all .txt file and doc file in a folder?
I am able to get all the file but unable to exclude .txt file and .doc files.
foreach (string f in Directory.GetFiles(#readpath))
{
List<string> list = new List<string>();
list.Add(f);
for (listcount = 0; listcount < list.Count; listcount++)
{
path2 = list[listcount];
creationdate = File.GetCreationTime(path2);
modidate = File.GetLastWriteTime(path2);
}
chkchecksum();
}
Replace
foreach (string f in Directory.GetFiles(#readpath))
With
foreach (string f in Directory.GetFiles(#readpath).Where(f => !(f.EndsWith(".doc", StringComparison.OrdinalIgnoreCase) && !f.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))))

Properly parsing strings line by line from a website

I have this being echo into a blank page:
echo "Testing|Testing1|Testing2|Testing3|Testing4<br/>";
echo "Something|Something1|Something2|Something3|Something4";
Now I have a listview. In this example it would create 2 rows with 5 columns. So my question is, how to read line by line to properly create the number of rows that are displayed on the website?
Here's my code so far:
WebClient client = new WebClient();
string downloadString = client.DownloadString("https://example.com/Testing.php");
string[] downloadString2 = downloadString.Split(
new char[]
{
(char)'|'
}, System.StringSplitOptions.RemoveEmptyEntries);
ListViewItem item = new ListViewItem(
new[]
{
downloadString2[0].ToString(),
downloadString2[1].ToString(),
downloadString2[2].ToString(),
downloadString2[3].ToString(),
downloadString2[4].ToString()
});
listView1.Items.Add(item);
(The columns are already created in the listview)
--
Edit: This worked fine for me:
WebClient client = new WebClient();
string downloadString = client.DownloadString("https://example.com/Testing.php");
string[] stringSeparators = new string[] { "<br/>" };
string[] Lines = downloadString.Split(stringSeparators, StringSplitOptions.None);
string[] things = new string[5]; // Fixed size. I might find a way later to make it dynamically
int i = 0;
foreach (string line in Lines)
{
string[] words = line.Split('|');
i = 0;
foreach (string word in words)
{
things[i] = word;
i++;
}
ListViewItem item = new ListViewItem(
new[]
{
things[0],
things[1],
things[2],
things[3],
things[4]
});
listView1.Items.Add(item);
}
not exactly what you want but you can try this
WebClient client = new WebClient();
string downloadString = client.DownloadString("https://example.com/Testing.php");
string[] stringSeparators = new string[] {"<br/>"};
string[] Lines = downloadString.Split(stringSeparators, StringSplitOptions.None);
foreach (string line in Lines)
{
string[] words = line.Split('|');
foreach (string word in words)
{
ListViewItem item = new ListViewItem();
item.add(word);
}
listView1.Items.Add(item);
}

How to find the Filename with the latest version in C#

I have a folder that is filled with dwg files so I just need to find the latest version of a File or if a File has no versions then copy it to a directory. For example here are three files:
ABBIE 08-10 #6-09H4 FINAL 06-12-2012.dwg
ABBIE 08-10 #6-09H4 FINAL 06-12-2012_1.dwg
ABBIE 08-10 #6-09H4 FINAL 06-12-2012_2.dwg
Notice the difference is one file has a _1 and another has a _2 so the latest file here is the _2. I need to keep the latest file and copy it to a directory. Some files will not have different versions so those can be copied. I cannot focus on the creation date of the file or the modified date because in many instances they are the same so all I have to go on is the file name itself. I'm sure there is a more efficient way to do this than what I will post below.
DirectoryInfo myDir = new DirectoryInfo(#"H:\Temp\Test");
var Files = myDir.GetFiles("*.dwg");
string[] fileList = Directory.GetFiles(#"H:\Temp\Test", "*FINAL*", SearchOption.AllDirectories);
ArrayList list = new ArrayList();
ArrayList WithUnderscores = new ArrayList();
string nameNOunderscores = "";
for (int i = 0; i < fileList.Length; i++)
{
//Try to get just the filename..
string filename = fileList[i].Split('.')[0];
int position = filename.LastIndexOf('\\');
filename = filename.Substring(position + 1);
filename = filename.Split('_')[0];
foreach (FileInfo allfiles in Files)
{
var withoutunderscore = allfiles.Name.Split('_')[0];
withoutunderscore = withoutunderscore.Split('.')[0];
if (withoutunderscore.Equals(filename))
{
nameNOunderscores = filename;
list.Add(allfiles.Name);
}
}
//If there is a number after the _ then capture it in an ArrayList
if (list.Count > 0)
{
foreach (string nam in list)
{
if (nam.Contains("_"))
{
//need regex to grab numeric value after _
var match = new Regex("_(?<number>[0-9]+)").Match(nam);
if (match.Success)
{
var value = match.Groups["number"].Value;
var number = Int32.Parse(value);
WithUnderscores.Add(number);
}
}
}
int removedcount = 0;
//Whats the max value?
if (WithUnderscores.Count > 0)
{
var maxval = GetMaxValue(WithUnderscores);
Int32 intmax = Convert.ToInt32(maxval);
foreach (FileInfo deletefile in Files)
{
string shorten = deletefile.Name.Split('.')[0];
shorten = shorten.Split('_')[0];
if (shorten == nameNOunderscores && deletefile.Name != nameNOunderscores + "_" + intmax + ".dwg")
{
//Keep track of count of Files that are no good to us so we can iterate to next set of files
removedcount = removedcount + 1;
}
else
{
//Copy the "Good" file to a seperate directory
File.Copy(#"H:\Temp\Test\" + deletefile.Name, #"H:\Temp\AllFinals\" + deletefile.Name, true);
}
}
WithUnderscores.Clear();
list.Clear();
}
i = i + removedcount;
}
else
{
//This File had no versions so it is good to be copied to the "Good" directory
File.Copy(#"H:\Temp\SH_Plats\" + filename, #"H:\Temp\AllFinals" + filename, true);
i = i + 1;
}
}
I've made a Regex based solution, and apparently come late to the party in the meantime.
(?<fileName>[A-Za-z0-9-# ]*)_?(?<version>[0-9]+)?\.dwg
this regex will recognise the fileName and version and split them into groups, a pretty simple foreach loop to get the most recent files in a dictionary (cos I'm lazy) and then you just need to put the fileNames back together again before you access them.
var fileName = file.Key + "_" + file.Value + ".dwg"
full code
var files = new[] {
"ABBIE 08-10 #6-09H4 FINAL 06-12-2012.dwg",
"ABBIE 08-10 #6-09H4 FINAL 06-12-2012_1.dwg",
"ABBIE 08-10 #6-09H4 FINAL 06-12-2012_2.dwg",
"Second File.dwg",
"Second File_1.dwg",
"Third File.dwg"
};
// regex to split fileName from version
var r = new Regex( #"(?<fileName>[A-Za-z0-9-# ]*)_?(?<version>[0-9]+)?\.dwg" );
var latestFiles = new Dictionary<string, int>();
foreach (var f in files)
{
var parsedFileName = r.Match( f );
var fileName = parsedFileName.Groups["fileName"].Value;
var version = parsedFileName.Groups["version"].Success ? int.Parse( parsedFileName.Groups["version"].Value ) : 0;
if( latestFiles.ContainsKey( fileName ) && version > latestFiles[fileName] )
{
// replace if this file has a newer version
latestFiles[fileName] = version;
}
else
{
// add all newly found filenames
latestFiles.Add( fileName, version );
}
}
// open all most recent files
foreach (var file in latestFiles)
{
var fileToCopy = File.Open( file.Key + "_" + file.Value + ".dwg" );
// ...
}
You can use this Linq query with Enumerable.GroupBy which should work(now tested):
var allFiles = Directory.EnumerateFiles(sourceDir, "*.dwg")
.Select(path => new
{
Path = path,
FileName = Path.GetFileName(path),
FileNameWithoutExtension = Path.GetFileNameWithoutExtension(path),
VersionStartIndex = Path.GetFileNameWithoutExtension(path).LastIndexOf('_')
})
.Select(x => new
{
x.Path,
x.FileName,
IsVersionFile = x.VersionStartIndex != -1,
Version = x.VersionStartIndex == -1 ? new Nullable<int>()
: x.FileNameWithoutExtension.Substring(x.VersionStartIndex + 1).TryGetInt(),
NameWithoutVersion = x.VersionStartIndex == -1 ? x.FileName
: x.FileName.Substring(0, x.VersionStartIndex)
})
.OrderByDescending(x => x.Version)
.GroupBy(x => x.NameWithoutVersion)
.Select(g => g.First());
foreach (var file in allFiles)
{
string oldPath = Path.Combine(sourceDir, file.FileName);
string newPath;
if (file.IsVersionFile && file.Version.HasValue)
newPath = Path.Combine(versionPath, file.FileName);
else
newPath = Path.Combine(noVersionPath, file.FileName);
File.Copy(oldPath, newPath, true);
}
Here's the extension method which i'm using to determine if a string is parsable to int:
public static int? TryGetInt(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
Note that i'm not using regex but string methods only.
Try this
var files = new My.Computer().FileSystem.GetFiles(#"c:\to\the\sample\directory", Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.dwg");
foreach (String f in files) {
Console.WriteLine(f);
};
NB: Add a reference to Microsoft.VisualBasic and use the following line at the beginning of the class:
using My = Microsoft.VisualBasic.Devices;
UPDATE
The working sample[tested]:
String dPath=#"C:\to\the\sample\directory";
var xfiles = new My.Computer().FileSystem.GetFiles(dPath, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.dwg").Where(c => Regex.IsMatch(c,#"\d{3,}\.dwg$"));
XElement filez = new XElement("filez");
foreach (String f in xfiles)
{
var yfiles = new My.Computer().FileSystem.GetFiles(dPath, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, string.Format("{0}*.dwg",System.IO.Path.GetFileNameWithoutExtension(f))).Where(c => Regex.IsMatch(c, #"_\d+\.dwg$"));
if (yfiles.Count() > 0)
{
filez.Add(new XElement("file", yfiles.Last()));
}
else {
filez.Add(new XElement("file", f));
};
};
Console.Write(filez);
Can you do this by string sort? The only tricky part I see here is to convert the file name to a sortable format. Just do a string replace from dd-mm-yyyy to yyyymmdd. Then, sort the the list and get the last record out.
This is what you want considering fileList contain all file names
List<string> latestFiles=new List<string>();
foreach(var groups in fileList.GroupBy(x=>Regex.Replace(x,#"(_\d+\.dwg$|\.dwg$)","")))
{
latestFiles.Add(groups.OrderBy(s=>Regex.Match(s,#"\d+(?=\.dwg$)").Value==""?0:int.Parse(Regex.Match(s,#"\d+(?=\.dwg$)").Value)).Last());
}
latestFiles has the list of all new files..
If fileList is bigger,use Threading or PLinq

Categories

Resources