Adding to listbox from multiple files and deleting doubled items - c#

As you can read in the title, I am trying to add listbox items to a listbox from multiple files. But I don't know how to read from all these files and how to delete the doubled lines (as some txt-files contain the same information).
A new file gets added every day, so I can't just read them all manually.
My code so far:
string directory = System.AppDomain.CurrentDomain.BaseDirectory;
DirectoryInfo dinfo = new DirectoryInfo(directory);
FileInfo[] Files = dinfo.GetFiles("*.txt");

First of all you need to identify every file you need to read.
Once you have all the files you need to read the data from each file into some form of storage for example a DataTable.
Once you have filled the DataTable you will need to populate the ListBox with the data.

From what you've got so far it looks like your next step will be to collect the data from each of the files (we can deal with removing duplicates afterwards).
So perhaps:
HashSet<something> myCollection = new HashSet<something>();
// perhaps <something> is just a string?
foreach (var file in Files)
{
// Collect what you need and pop it in the collection
}
// Remove duplicates
To get the info out of the files you'll probably need a StreamReader.
Fore removal of duplicates try HashSets.

you can try this code:
in this code all unique data will be stored in lstData and you can bind your control using this
string directory = System.AppDomain.CurrentDomain.BaseDirectory;
DirectoryInfo dinfo = new DirectoryInfo(directory);
FileInfo[] Files = dinfo.GetFiles("*.txt");
List<string> lstData = new List<string>();
foreach (var file in Files)
{
using (StreamReader sr = File.OpenText(file.FullName))
{
string s = String.Empty;
while ((s = sr.ReadLine()) != null)
{
if (!lstData.Contains(s))
{
lstData.Add(s);
}
}
}
}

Related

C# WPF How do I display the contents of a .txt file into a list box?

Say I have a txt file with this content:
Tom, 11
Jason, 12
Gary, 13
Ted, 14
The WPF is just a list box.
What would I need to do for the list box, to show the names inside the txt file when I start the program.
This is a very simple question, but I cant figure it out. I don't know where the txt file needs to be saved and I don't know how to call it in the ".cs"
This is code which read next line to list,then read how to add this to listbox
List<string> lines = new List<string>();
using (StreamReader r = new StreamReader(f))
{
string line;
while ((line = r.ReadLine()) != null)
{
lines.Add(line);
}
}
This is example how to binding list to listbox:
eventList.ItemsSource = lines;
Text file can be anywhere as you can specify path to it while opening. You can put it inside solution folder to make path shorter.
Then in main method you write something like
var MyList = new List<string>();
using (var streamReader = File.OpenText(pathToYourTextFile))
{
var s = string.Empty;
while ((s = streamReader.ReadLine()) != null)
MyList.Add(s);
}
myListbox.ItemsSource = MyList;

File is already use in some other process

Here I want to delete line in a textfiles containg specific string like "21309#003" where item1 is a filename but It shows runtime exception that item1 (file) is already use in some process.How I Solve this problem.I am new in .net C#.
private void button1_Click(object sender, EventArgs e)
{
var selectedItems = listBox1.SelectedItems.Cast<String>().ToList();
foreach (var item in selectedItems)
{
listBox1.Items.Remove(item);
}
foreach (var item1 in selectedItems)
{
listBox1.Items.Remove(item1);
string line = null;
//string line_to_delete = "the line i want to delete";
using (StreamReader reader = new StreamReader(item1))
//item1= "C:\\IMP2711\\textpresent.txt"
{
using (StreamWriter writer = new StreamWriter(item1))
{
while ((line = reader.ReadLine()) != null)
{
//if (String.Compare(line, #"*21349#003*") == 0)
//if (!line.Contains("21349#003") )
if (!line.StartsWith("21349#003"))
{**strong text**
writer.WriteLine(line);
}
}
}
You are reading and writing to the same file at the same time.
var item2 = item1;
If the file is not to big you can read the lines into memory and then write the lines you want to keep back to the file. We can even simplify your code a little bit.
File.WriteAllLines(item1,
File.ReadLines(item1).Where(l => !l.StartsWith("21349#003")).ToList());
Another option if the file is very large is to write to a temporary file. Delete the original and then rename the temporary.
var tmp = Path.GetTempFileName();
File.WriteAllLines(tmp, File.ReadLines(item1).Where(l => !l.StartsWith("21349#003")));
File.Delete(item1);
File.Move(tmp, item1);
If your file is small first read it to memory and then try to write on it, you have two stream on the same file, a file can share between multiple streams but you can not modify a file when it is open by another stream, if your file is huge and you can not moved to memory you can create a temp file and write to temp file when your reading finished replacing original file with temp file and removing temp file.
There's some process that's locking the file c:\imp2711\textpresent.txt. You have to find and kill it.
To find it out, please refer to this question: https://superuser.com/questions/117902/find-out-which-process-is-locking-a-file-or-folder-in-windows

automate openFileDialog process in c#

I have tried this code it would open the file dialog to the correct location and there is only one xml file which needs to selected ( where i need to select it and click on open ) instead of selecting the file and click open to process the file is there any way to disable the open button on open file dialog. Here my xml file changes everyday. i have given *.xml but gives me a error Illegal characters in path.. my file format is this.
lborough vehicles_in 2014-06-05.xml == this changes everyday according to date.
Without clicking on open how to select the file.
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "XML Files (*.xml)|*.xml";
string initPath = Path.GetFullPath("C:/Users/IT-Administrator/Desktop/LUVS/");
dialog.InitialDirectory = Path.GetFullPath(initPath);
tblVehicles = new DataTable();
dv = new DataView(tblVehicles);
if (dialog.ShowDialog() == DialogResult.OK)
{
if (dialog.FileName.Length > 0)
{
//Load Schema and Vehicle_In XML file
tblVehicles.ReadXmlSchema(Path.Combine(applicationFolder, "vehicles_in.xsd"));
tblVehicles.ReadXml(dialog.FileName);
this.dataGridView1.DataSource = tblVehicles;
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.ReadOnly = true;
**Update**
I have tried this can you tell me how to open the file from Directory.get files at runtime
string[] filePaths = Directory.GetFiles(#"C:\Users\IT-Administrator\Desktop\LUVS/", "*.xml", SearchOption.AllDirectories);
FileStream stream = File.Open(#"C:\Users\IT-Administrator\Desktop\LUVS*.xml",
FileMode.Open);
tblVehicles = new DataTable();
dv = new DataView(tblVehicles);
tblVehicles.ReadXmlSchema(Path.Combine(applicationFolder, "vehicles_in.xsd"));
tblVehicles.ReadXml(stream);
Your attempted solution at the end doesn't quite get it:
/* Gives you an array of file names */
string[] filePaths = Directory.GetFiles(#"C:\Users\IT-Administrator\Desktop\LUVS/", "*.xml", SearchOption.AllDirectories);
FileStream stream = File.Open(#"C:\Users\IT-Administrator\Desktop\LUVS*.xml",
FileMode.Open);
You aren't using the array, but instead just trying to open a wildcard path; You can't do that. File.Open only accepts a single file path.
Instead, try something more like this:
/* Gives you an array of file names */
string[] filePaths = Directory.GetFiles(#"C:\Users\IT-Administrator\Desktop\LUVS/", "*.xml", SearchOption.AllDirectories);
// Work with each file individually
foreach(var filePath in filePaths)
{
using(FileStream stream = File.Open(filePath, FileMode.Open))
{
tblVehicles = new DataTable();
dv = new DataView(tblVehicles);
tblVehicles.ReadXmlSchema(Path.Combine(applicationFolder, "vehicles_in.xsd"));
tblVehicles.ReadXml(stream);
// Do whatever you need to do with the data from this one file, then move on....
{
}
Is there any reason that you can't use Directory.GetFiles to get all files in a directory and use File.Open to get the file? Why do you want to do this with a FileDialog, if you don't want the FileDialog?
Update:
//Load Schema and Vehicle_In XML file
tblVehicles.ReadXmlSchema(Path.Combine(applicationFolder, "vehicles_in.xsd"));
// Get all XML files from the files directory
string[] filePaths = Directory.GetFiles(#"files\", "*.xml", SearchOption.AllDirectories);
// Read the first XML file in the files directory
tblVehicles.ReadXml(filePaths[0]);
Is this what you asked for?
As you want to select your file and inmediately work with it, you want a button behaviour. Best way here is to make your own UserControl showing files existing on your directory.
1. Get files from directory
2. Show dialog with buttons, every buttons asociated to its file.
3. On button click, close dialog and pass file to your method.
You could use SendKeys() but it's clunky, and if the user moves focus elsewhere you might end up sending the keystrokes to the wrong window.
openFileDialog isn't very customizable, so you might want to consider using openFolderDialog and append the known filename to the user selected directory.

How to read multiple files from server into c#

I want to know how to read multiple (about 500-1000) text files which are located on a server.
So far, I've written code for a program that only reads a single text file.
Here's how I'm currently reading a single file.
public void button1_Click(object sender, EventArgs e)
{
// Reading/Inputing column values
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string[] fileLines = File.ReadAllLines(ofd.FileName);
I would like to get rid of the open file dialog box, and let the program automatically read the 500-1000 text files where are located in the sever.
I'm thinking something along the lines of
for (int i =0; i<numFiles; i++)
{
//just use string[] fileLines =File.ReadAllLines()
//how would i specify the path for multiple files?
}
Questions are then:
How would I approach this?
How exactly should I get the number of files?
(I'm guessing I'd have to read the server file which contains them.)
You can use Directory.GetFiles(string path) to get all files from a certain directory. You can then use a foreach loop to iterate through all the files in that directory and do your processing.
You can use recursion to loop through all directories. Using Directory.EnumerateFiles also allows you to use a foreach loop so you don't have to worry about the file count.
private static void ReadAllFilesStartingFromDirectory(string topLevelDirectory)
{
const string searchPattern = "*.txt";
var subDirectories = Directory.EnumerateDirectories(topLevelDirectory);
var filesInDirectory = Directory.EnumerateFiles(topLevelDirectory, searchPattern);
foreach (var subDirectory in subDirectories)
{
ReadAllFilesStartingFromDirectory(subDirectory);//recursion
}
IterateFiles(filesInDirectory, topLevelDirectory);
}
private static void IterateFiles(IEnumerable<string> files, string directory)
{
foreach (var file in files)
{
Console.WriteLine("{0}", Path.Combine(directory, file));//for verification
try
{
string[] lines = File.ReadAllLines(file);
foreach (var line in lines)
{
//Console.WriteLine(line);
}
}
catch (IOException ex)
{
//Handle File may be in use...
}
}
}
Also note Directory.EnumerateFiles provides overload that lets you provide a search pattern to narrow the scope of the files.
How you go about getting your files depends on if they are all located in the same directory of if you'll need to recursively search through a directory and all child directories. Directory.GetFiles is where you want to start. It has 3 overloads seen here. So you might try something like this:
string path = "\mypath\tosomehwere";
string searchPattern = "*.txt";
string[] MyFiles = Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories);
Then just loop through the string array and proccess each file as you would normally.
foreach (string filePath in MyFiles)
{
MyFileProcessMethod(filePath)
}
Path.GetFileName(filePath) will return the individual text file name should you need it for your processing requirements.

How to list text files in the selected directory in a listbox?

How can I list the text files in a certain directory (C:\Users\Ece\Documents\Testings) in a listbox of a WinForm(Windows application)?
// What directory are the files in?...
DirectoryInfo dinfo = new DirectoryInfo(#"C:\TestDirectory");
// What type of file do we want?...
FileInfo[] Files = dinfo.GetFiles("*.txt");
// Iterate through each file, displaying only the name inside the listbox...
foreach( FileInfo file in Files )
{
listbox1.Items.Add(file.Name);
}
// A statement, followed by a smiley face...
That oughta do it. ;o)
To get the txt files, try this:
var folder = #"C:\Users\Ece\Documents\Testings";
var txtFiles = Directory.GetFiles(folder, "*.txt");
listBox.Items.AddRange(txtFiles);

Categories