Splitting String Array, then using each element separately - c#

I'm trying to split an array, which gets its data from a list string. I've managed to split the string, but I can't seem to work out how to use each element of the split string separately. Here's what I have:
DriveInfo[] loadedDrives = DriveInfo.GetDrives();
foreach (DriveInfo ld in loadedDrives)
{
if (ld.DriveType == DriveType.Removable)
{
if (ld.IsReady == true)
{
deviceInfo.Add(ld.VolumeLabel + ": , " + ld.TotalSize + ": , " + ld.AvailableFreeSpace + ": , " + ld.DriveFormat); //Add data to list
}
}
}
foreach (String st in deviceInfo)
{
string[] deviceSel;
deviceSel = st.Split(splitChar);
string toDisplay = string.Join(Environment.NewLine, deviceSel);
MessageBox.Show(toDisplay);
}
Now the output I get from this is something like:
USB Device Name
Total Storage Size
Total Free Space
Type of Drive Format
These change depending on the USB in question. Is there a way that I can get each one of those points in separate variables, or is there a better way to what I have done?

Would something like this work:
deviceSel = st.Split(splitChar);
string toDisplay = "";
foreach (string device in deviceSel)
{
toDisplay += device + Environment.NewLine;
}
MessageBox.Show(toDisplay);
You can either do it in a loop or access based on index as #dasblinkenlight suggested.

Related

Getting HDD info only returns C drive info none others. c#

I am putting together a program that pulls out a bunch of info from a PC and sends it to a server. I am currently working on trying to pull hdd info from the pc that has multiple drives but i can only get it to work with the first drive. Below is the code that pulls out the actual drive info and below that is the code that writes it out to console:
public static string CurrentDiskUsage()
{
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
try
{
if (drive.IsReady)
{
double result = 100 * (double) drive.TotalFreeSpace / drive.TotalSize;
result = Math.Round(result, 2, MidpointRounding.AwayFromZero);
string driveInformation = null;
driveInformation += drive.Name + "\n" + drive.DriveFormat + "\n" + "Drive total size: " + FormatBytes(drive.TotalSize) + "\n" + "Drive total free space: " + FormatBytes(drive.TotalFreeSpace) + "\n" + "Free space as percentage: " + result + "% \n ";
return driveInformation;
}
}
catch (Exception e)
{
return "Fail";
Console.WriteLine(e);
}
}
return "Fail";
}
Writes info to console
String[] Content = new string[7];
Content[0] = reportFunctions.GetOsName();
Content[1] = reportFunctions.IsSoftwareInstalled();
Content[2] = reportFunctions.CurrentLoggedInUser();
Content[3] = reportFunctions.GetPcName();
Content[4] = reportFunctions.CurrentDiskUsage();
int i = 0;
while (i < 6)
{
Console.WriteLine(Content[i]);
i++;
}
}
At the end of the first loop you have "return "Fail";"
Remove this line as it is blocking further effort. You probably also want to remove the return from the exception as if your CD drive say drive D isnt ready your code will stop, and not continue too
EDIT: instead of the returns - as you also try to return a string of drive info - just write this data out to console. Return means stop doing what Im doing now and go back to whatever ran me.
Your code needs to look more like this (PS you should also use Environment.NewLine not \n as this always returns the correct linefeed for the OS)
public static string CurrentDiskUsage()
{
String driveInformation =""; //your code overwrote this with each loop
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
try
{
if (drive.IsReady)
{
double result = 100 * (double) drive.TotalFreeSpace / drive.TotalSize;
result = Math.Round(result, 2, MidpointRounding.AwayFromZero);
driveInformation += drive.Name + Environment.NewLine + drive.DriveFormat + Environment.NewLine + "Drive total size: " + FormatBytes(drive.TotalSize) + Environment.NewLine + "Drive total free space: " + FormatBytes(drive.TotalFreeSpace) + Environment.NewLine + "Free space as percentage: " + result + "% "+Environment.NewLine;
}
}
catch (Exception e)
{
DriveInformation+="Fail:"+Drive.Name+Environment.NewLine+e.Message;
}
}
return driveInformation;
}

generic export of the contents of a list

I quite often use Lists to store content as a sort of database.
I would create a specific Class that holds a series of propertiesafter which I would export the contents of that list to an external textfile.
For the export I would use something like:
string output = string.empty;
for (int i=0; i<myList.count; i++)
{
output += myList[i].property1 + ";" + myList[i].property2 + ";" + myList[i].property3 + ";" + myList[i].property4 + ";" + myList[i].property5 + Environtment.NewLine;
}
File.WriteAllText(#"c:\mytextfile.txt", output);
This works like a charm, the only issue is that I have to create an export-routine for every list with a specific class in the application.
I would like to make this a bit more generic in the sense that I would like to create a single export-routine, in which I can pass the name of the List which will then automatically detect the number of parameters in the List and next, export all the different values into the textfile which would have the name of the List.
Something like this pseudo-code:
private void (List selectedList)
{
for (int i=0; i<selectedList.count; i++)
{
output += string.join(";",items) + environment.NewLine;
}
File.WriteAllText(filepath + selectedlist + ".txt", output);
}
Does anybody have an idea on how to solve this?
Thank you.
To get a list of properties on an object is going to involve using reflection.
This is a little rough since I'm not in front of VS at the moment, but if you pass it a List<Foo> it will write a file called Foo.txt
private const string rootPath = #"C:\Temp\";
private static void WriteFile<T>(List<T> selectedList)
{
var props = typeof(T).GetProperties();
var sb = new StringBuilder();
foreach (var item in selectedList) {
foreach (var prop in props) {
var val = prop.GetValue(item);
sb.Append(val);
sb.Append(";");
}
}
sb.AppendLine();
var fileName = string.Format("{0}{1}.txt", rootPath, typeof (T).Name);
File.WriteAllText(fileName, sb.ToString());
}
Please be aware using reflection can be quite slow. There is plenty of room for optimisation in the above.

Adding text items from a csv file, to a listbox only when certain a string matches a string from that csv file

So I've been trying to figure out how to bring an entire line of a .csv file but only the ones who's first string matches another one.
This is what I got so far, all im getting back in my listbox is info from the same random line.
If you guys can help me with the logic it would help out a lot thanks
cbocustinfo.Items.Clear();
lstcustinfo.Items.Clear();
StreamReader infile, transdata;
infile = File.OpenText(#"E:\AS2customers.csv");
transdata= File.OpenText(#"E:\AS2data.csv");
string[] custinfo, names;
string[] custtrans;
do
{
custtrans = transdata.ReadLine().Split(',');
if (custinfo[1] == custtrans[0])
{
lstcustinfo.Items.Add(custtrans[3] + " " + custtrans[4]);
}
}
while (transdata.EndOfStream != True);
infile.Close();
transdata.Close();
Here is where I initialize custinfo
do
{
custinfo = infile.ReadLine().Split(',');
names = custinfo[0].Split(' ');
cbocustinfo.Items.Add(names[0] +" "+ names[1]+ " " + custinfo[1]);
}
while (infile.EndOfStream != true);
If I understand what you're trying to do correctly, maybe it would be easier to just read the files into two strings, then do the splitting and looping over those. I don't know your file formats, so this may be doing unnecessary processing (looping through all the transactions for every customer).
For example:
cbocustinfo.Items.Clear();
lstcustinfo.Items.Clear();
var customers = File.ReadAllText(#"E:\AS2customers.csv")
.Split(new []{Environment.NewLine}, StringSplitOptions.None);
var transactions = File.ReadAllText(#"E:\AS2data.csv")
.Split(new []{Environment.NewLine}, StringSplitOptions.None);
foreach (var customer in customers)
{
var custInfo = customer.Split(',');
var names = custInfo[0].Split(' ');
cbocustinfo.Items.Add(names[0] + " " + names[1]+ " " + custinfo[1]);
foreach (var transaction in transactions)
{
var transInfo = transaction.Split(',');
if (custInfo[1] == transInfo[0])
{
lstcustinfo.Items.Add(transInfo[3] + " " + transInfo[4]);
}
}
}

Make string checker more efficient

I am using the following code to check if a string is contained within another string -
foreach (string testrecord in testlist)
{
foreach (string realrecord in reallist)
{
if ((Regex.Replace(testrecord , "[^0-9a-zA-Z]+", "")
.Contains((
Regex.Replace(realrecord, "[^0-9a-zA-Z]+", "")))
&&
((Regex.Replace(realrecord, "[^0-9a-zA-Z]+", "") != "")
&&
((Regex.Replace(realrecord, "[^0-9a-zA-Z]+", "").Length >= 4)))))
{
matchTextBox.AppendText("Match: " + testrecord + " & " + realrecord + Environment.NewLine);
}
}
}
However the runtime for this to finish is taking quite a while. Since I added the special character regex removal the runtime is taking a lot longer however the regex is definitely required.
Is there a more efficient way of applying this regex? I tried to add it to the foreach string variables however you cannot alter them as they are in a foreach loop.
Optimized version:
// Do not put text into matchTextBox direct:
// it makes the control re-painting each time you change the text
// Instead, collect all the text into StringBuffer
StringBuilder Sb = new StringBuilder();
// Pull out as much as you can from the inner loop,
// that's why I've changed the loops' order:
// first loop on reallist, then on testlist
foreach (string realrecord in reallist) {
// Cache Regex.Replace result
String realCleaned = Regex.Replace(realrecord, "[^0-9a-zA-Z]+", "");
// Test as early as possible
if (realCleaned.Length < 4)
continue;
// You don't need to test realCleaned != "";: realCleaned.Length < 4 is enough
foreach (string testrecord in testlist) {
// Cache Regex.Replace result: it's a little bit overshoot here, but if some
// more tests are added it'll be helpful
String testCleaned = Regex.Replace(testrecord, "[^0-9a-zA-Z]+", "");
if (testCleaned.Contains(realCleaned))
Sb.AppendLine("Match: " + testrecord + " & " + realrecord);
}
}
// At last matchTextBox.Text change
matchTextBox.AppendText(Sb.ToString());
This should be a bit quicker (one regex operation per testrecord):
var strippedRealList = reallist.Select(s => Regex.Replace(s, "[^0-9a-zA-Z]+", ""))
.Where(s => s.Length >= 4)
.ToArray();
foreach (string realrecord in reallist)
{
strippedRealList.Where(s => realrecord.Contains(s))
.ToList()
.ForEach(s =>
matchTextBox.AppendText("Match: "
+ s
+ " & "
+ realrecord
+ Environment.NewLine));
}
I wonder that you are using Regex to achieve your purpose ignoring the fact that you can also achieve this by only using .Contains() method such that your code should be simple and faster then before
foreach (string testrecord in testlist)
{
foreach (string realrecord in reallist)
{
if(testrecord.Contains(realrecord))
{
matchTextBox.AppendText("Match: " + testrecord + " & " + realrecord + Environment.NewLine);
}
}
}

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