I have a group of delimited text files I need to read, create a class and objects, and store members inside. I am a beginner that's just looking to be pointed in the right direction. Any help would be appreciated greatly. Thank you very much.
I made a class with objects with:
public string left;
public string right;
and my form code :
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog of = new OpenFileDialog();
of.ShowDialog();
textBox1.Text = of.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(textBox1.Text);
textBox2.Text = sr.ReadToEnd();
// sr.Close();
}
private void button3_Click(object sender, EventArgs e)
{
string[] split1 = textBox2.Text.Split(';');
foreach (string segment in split1)
{
//split sub-segment
string[] split2 = segment.Split(':');
//check if it's valid
if (split2.Count().Equals(2))
{
id textfile = new id();
textfile.left += // ????
id textfile1 = new id();
textfile.right += // ????
Generally, it's much preferable to use JSON or XML to save data to text files rather than delimited text or custom formats. That's because good JSON and XML support is available in my languages and it's easy to work with.
public class MyCustomClass //this class will hold your data
{
public string Left {get; set;}
public string Right {get;set;}
}
MyCustomClass mcc=new MyCustomClass(); //create an instance of your class
mcc.Left="yes"; //set some properties
mcc.Right="nope";
string json=JsonConvert.SerializeObject(mcc); //convert to JSON string
File.WriteAllText("mcc.txt",json); //save to file
//later on, when you want to read it back from the file
string json=File.ReadAllText("mcc.text"); //read from file into a string
MyCustomClass mcc=JsonConvert.DeserializeObject<MyCustomClass>(json); //convert the string back to an instance of MyCustomClass
Above, we use Json.NET which is a library available for the .NET Framework (available on NuGet). We use it to convert our object to a string (serialize) and then later on to convert it back to an object (deserialize). Note that in order to use the JsonConvert class, you'll need the Json.NET references and to add a using statement at the top of your class using Newtonsoft.Json;.
What you're looking for is serialization. When you have a known structure (like your class with string left and string right), you want to write that structure out to a text file. Then later, you want to read that information back in and automatically populate the class with each of the values.
As mason pointed out, JSON is fairly easy to setup. You create the class structure that you want, and tell JSON to save that out to a specified file (via SerializeObject).
Since .NET allows for reflection, JSON is able to turn the text file back into the contents of a class without you having to manually 'myClass.left = [some_value_from_json]'.
Personally, I'd go with JSON or XML, since naming your blocks of data means it is both more readable, and that your parser is able to handle someone rearranging the data (it doesn't matter if the file defines left before it defines right). If you rearranged a .CSV file, then you get data corruption.
Reading delimited files is common and there are many approaches to the subject. Personally I use a streamReader to read in the file and split it on the delimiter:
Foo foo = new Foo(); // custom class
string file = "export.CSV";
if (System.IO.File.Exists(file))
{
// Do work
using (var reader = new StreamReader(file))
{
while (!reader.EndOfStream)
{
// split on the delimeter
var readLine = reader.ReadLine();
if (readLine == null) continue;
var lines = readLine.Split(new[] { ',' });
foreach (string s in lines)
{
// do something with the data from the line
}
// alternatively, you could specify your objects if your files
// layout never changes. Just be careful to catch the exceptions!
foo.bar = lines[0];
foo.baz = lines[1];
}
}
}
Related
There are a lot of different ways to read and write files (text files, not binary) in C#.
I just need something that is easy and uses the least amount of code, because I am going to be working with files a lot in my project. I only need something for string since all I need is to read and write strings.
Use File.ReadAllText and File.WriteAllText.
MSDN example excerpt:
// Create a file to write to.
string createText = "Hello and Welcome" + Environment.NewLine;
File.WriteAllText(path, createText);
...
// Open the file to read from.
string readText = File.ReadAllText(path);
In addition to File.ReadAllText, File.ReadAllLines, and File.WriteAllText (and similar helpers from File class) shown in another answer you can use StreamWriter/StreamReader classes.
Writing a text file:
using(StreamWriter writetext = new StreamWriter("write.txt"))
{
writetext.WriteLine("writing in text file");
}
Reading a text file:
using(StreamReader readtext = new StreamReader("readme.txt"))
{
string readText = readtext.ReadLine();
}
Notes:
You can use readtext.Dispose() instead of using, but it will not close file/reader/writer in case of exceptions
Be aware that relative path is relative to current working directory. You may want to use/construct absolute path.
Missing using/Close is very common reason of "why data is not written to file".
FileStream fs = new FileStream(txtSourcePath.Text,FileMode.Open, FileAccess.Read);
using(StreamReader sr = new StreamReader(fs))
{
using (StreamWriter sw = new StreamWriter(Destination))
{
sw.Writeline("Your text");
}
}
The easiest way to read from a file and write to a file:
//Read from a file
string something = File.ReadAllText("C:\\Rfile.txt");
//Write to a file
using (StreamWriter writer = new StreamWriter("Wfile.txt"))
{
writer.WriteLine(something);
}
using (var file = File.Create("pricequote.txt"))
{
...........
}
using (var file = File.OpenRead("pricequote.txt"))
{
..........
}
Simple, easy and also disposes/cleans up the object once you are done with it.
#AlexeiLevenkov pointed me at another "easiest way" namely the extension method. It takes just a little coding, then provides the absolute easiest way to read/write, plus it offers the flexibility to create variations according to your personal needs. Here is a complete example:
This defines the extension method on the string type. Note that the only thing that really matters is the function argument with extra keyword this, that makes it refer to the object that the method is attached to. The class name does not matter; the class and method must be declared static.
using System.IO;//File, Directory, Path
namespace Lib
{
/// <summary>
/// Handy string methods
/// </summary>
public static class Strings
{
/// <summary>
/// Extension method to write the string Str to a file
/// </summary>
/// <param name="Str"></param>
/// <param name="Filename"></param>
public static void WriteToFile(this string Str, string Filename)
{
File.WriteAllText(Filename, Str);
return;
}
// of course you could add other useful string methods...
}//end class
}//end ns
This is how to use the string extension method, note that it refers automagically to the class Strings:
using Lib;//(extension) method(s) for string
namespace ConsoleApp_Sandbox
{
class Program
{
static void Main(string[] args)
{
"Hello World!".WriteToFile(#"c:\temp\helloworld.txt");
return;
}
}//end class
}//end ns
I would never have found this myself, but it works great, so I wanted to share this. Have fun!
These are the best and most commonly used methods for writing to and reading from files:
using System.IO;
File.AppendAllText(sFilePathAndName, sTextToWrite);//add text to existing file
File.WriteAllText(sFilePathAndName, sTextToWrite);//will overwrite the text in the existing file. If the file doesn't exist, it will create it.
File.ReadAllText(sFilePathAndName);
The old way, which I was taught in college was to use stream reader/stream writer, but the File I/O methods are less clunky and require fewer lines of code. You can type in "File." in your IDE (make sure you include the System.IO import statement) and see all the methods available. Below are example methods for reading/writing strings to/from text files (.txt.) using a Windows Forms App.
Append text to an existing file:
private void AppendTextToExistingFile_Click(object sender, EventArgs e)
{
string sTextToAppend = txtMainUserInput.Text;
//first, check to make sure that the user entered something in the text box.
if (sTextToAppend == "" || sTextToAppend == null)
{MessageBox.Show("You did not enter any text. Please try again");}
else
{
string sFilePathAndName = getFileNameFromUser();// opens the file dailog; user selects a file (.txt filter) and the method returns a path\filename.txt as string.
if (sFilePathAndName == "" || sFilePathAndName == null)
{
//MessageBox.Show("You cancalled"); //DO NOTHING
}
else
{
sTextToAppend = ("\r\n" + sTextToAppend);//create a new line for the new text
File.AppendAllText(sFilePathAndName, sTextToAppend);
string sFileNameOnly = sFilePathAndName.Substring(sFilePathAndName.LastIndexOf('\\') + 1);
MessageBox.Show("Your new text has been appended to " + sFileNameOnly);
}//end nested if/else
}//end if/else
}//end method AppendTextToExistingFile_Click
Get file name from the user via file explorer/open file dialog (you will need this to select existing files).
private string getFileNameFromUser()//returns file path\name
{
string sFileNameAndPath = "";
OpenFileDialog fd = new OpenFileDialog();
fd.Title = "Select file";
fd.Filter = "TXT files|*.txt";
fd.InitialDirectory = Environment.CurrentDirectory;
if (fd.ShowDialog() == DialogResult.OK)
{
sFileNameAndPath = (fd.FileName.ToString());
}
return sFileNameAndPath;
}//end method getFileNameFromUser
Get text from an existing file:
private void btnGetTextFromExistingFile_Click(object sender, EventArgs e)
{
string sFileNameAndPath = getFileNameFromUser();
txtMainUserInput.Text = File.ReadAllText(sFileNameAndPath); //display the text
}
Or, if you are really about lines:
System.IO.File also contains a static method WriteAllLines, so you could do:
IList<string> myLines = new List<string>()
{
"line1",
"line2",
"line3",
};
File.WriteAllLines("./foo", myLines);
It's good when reading to use the OpenFileDialog control to browse to any file you want to read. Find the code below:
Don't forget to add the following using statement to read files: using System.IO;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = File.ReadAllText(openFileDialog1.FileName);
}
}
To write files you can use the method File.WriteAllText.
class Program
{
public static void Main()
{
//To write in a txt file
File.WriteAllText("C:\\Users\\HP\\Desktop\\c#file.txt", "Hello and Welcome");
//To Read from a txt file & print on console
string copyTxt = File.ReadAllText("C:\\Users\\HP\\Desktop\\c#file.txt");
Console.Out.WriteLine("{0}",copyTxt);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//Write a file
string text = "The text inside the file.";
System.IO.File.WriteAllText("file_name.txt", text);
//Read a file
string read = System.IO.File.ReadAllText("file_name.txt");
MessageBox.Show(read); //Display text in the file
}
Reading from file
string filePath = #"YOUR PATH";
List<string> lines = File.ReadAllLines(filePath).ToList();
Writing to file
List<string> lines = new List<string>();
string a = "Something to be written"
lines.Add(a);
File.WriteAllLines(filePath, lines);
Simply:
String inputText = "Hello World!";
File.WriteAllText("yourfile.ext",inputText); //writing
var outputText = File.ReadAllText("yourfile.ext"); //reading
You're looking for the File, StreamWriter, and StreamReader classes.
I want to store variables in a .txt file - like I always see in peoples config.txt files, where it's like:
var_name = ['"test url"']
I've got the code below that opens the file and reads it (at the moment just debugging and displays what's in the file, at the moment just 1 variable)
System.IO.StreamReader myFile = new System.IO.StreamReader("C:\\conf\\config.txt");
string myString = myFile.ReadToEnd();
myFile.Close();
MessageBox.Show(myString);
What's in the file is
file_name="C:\\test.txt"
Now I'd like to be able to use that variable in my functions in my VB form. How do I go about doing this? And also, how can I do multiple; so I can have basically a big list of vars that the form loads at launch?
So for example:
// Opens file and reads all variables
// Saves all variables to form
// Can now use varaible in form, e.g. messageBox.Show(file_name);
I'm new to C#, I imagine it's similar to an include but the include is local instead of part of the project.
Disclamer: standard practice (i.e. Settings) usually is the best policy, however the question has been asked and can be asnwered:
I suggest using dictionary, e.g.
Dictionary<String, String> MySettings = File
.ReadLines(#"C:\conf\config.txt")
.ToDictionary(line => line.Substring(0, line.IndexOf('=')).Trim(),
line => line.Substring(line.IndexOf('=') + 1).Trim().Trim('"'));
...
String testUrl = MySettings[var_name];
However, if you prefer "variables" you can try ExpandoObject:
dynamic ExpSettings = new ExpandoObject();
var expandoDic = (IDictionary<string, object>) ExpSettings;
foreach (var pair in MySettings)
expandoDic.Add(pair.Key, pair.Value);
...
String testUrl = ExpSettings.var_name;
I store and load data (or variables) with Json Deserialization/ serialization in c#.
Here is Serialiazation: I make an object (postlist which is an object list) that i want to save in a text file That way:
private void save_file()
{
string path = Directory.GetCurrentDirectory() + #"\list.txt";
string json = JsonConvert.SerializeObject(postlist);
File.WriteAllText(path, json);
Application.Exit();
}
You need to install Newtonsoft.Json: http://www.newtonsoft.com/json
.You can do it with the Nuget tool console.
Don"t forget to use:
using Newtonsoft.Json;
Here is a way to get all your data from the text file, this is the deserialization:
private void read_file_list()
{
string line;
try
{
using (StreamReader sr = new StreamReader("list.txt"))
{
line = sr.ReadToEnd();
}
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
postlist = JsonConvert.DeserializeObject<List<Post>>(line, jsonSerializerSettings);
}
catch
{
// catch your exception if you want
}
}
And here is how i store all my text in my object list "postlist".
Newtonsoft is very usefull and easy to use, i mostly use it to get data from api's.
This my first answer I hope it will help you.
Currently trying to create a string from a text file, however their seems to be an error preventing the stream reader from reading the text file correctly.
private string testString = "Cheese";
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() != DialogResult.Cancel)
{
fileName = openFileDialog.FileName;
LoadFile();
}
}
private void LoadFile()
{
String lineFromFile = "Chicken";
*StringBuilder RawFileInput = new StringBuilder();
using (StreamReader reader = new StreamReader(fileName))
{
while ((lineFromFile = reader.ReadLine()) != null)
{
RawFileInput.AppendLine(lineFromFile);
}
}*
testString = lineFromFile;
testTB.Text = testString;
}
The output should the code execute has the output textbox be empty, however should the block of code between the asterisks be commented out, the output textbox obviously displays the test phrase of Chicken. As such I'm pretty sure there is a problem with this particular block, however I can't seem to figure out what.
Thanks in advance.
If I understood well your code, you are trying to set the testTB.Text with the text in your file. Taking that in account, shouldn't your last lines be:
testString = RawFileInput.ToString();
testTB.Text = testString;
You can achieve the same result with no need of a StringBuilder, replacing your whole LoadFile method with this line:
testTB.Text = File.ReadAllText(fileName);
You should be able to read a document in entirety, like the following:
var builder = new StringBuilder();
using(var reader = new StreamReader(path))
builder.Append(reader.ReadToEnd());
That would be the ideal, as it is more performant than ReadAllText.
ReadToEnd works best when you need to read all the input from the
current position to the end of the stream. If more control is needed
over how many characters are read from the stream, use the
Read(Char[], Int32, Int32) method overload, which generally results in
better performance. ReadToEnd assumes that the stream knows when it
has reached an end. For interactive protocols in which the server
sends data only when you ask for it and does not close the connection,
ReadToEnd might block indefinitely because it does not reach an end,
and should be avoided.
If you're wanting the contents of a file to populate a textbox, just set the Multiline property to true, and use File.ReadAllLines()
testTb.Lines = File.ReadAllLines(fileName);
It's simple what I'm trying to do; when I click a button, my app should check if textBox1.Text has a line from a text file.
Note: I don't want to check if textbox has all the text file in it, just to see if it has a LINE from it.
I tried this with no success:
private void acceptBtn_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(usersPath);
string usersTXT = sr.ReadLine();
if (user_txt.Text == usersTXT)
{
loginPanel.Visible = false;
}
}
Hope someone can help me. Thanks in Advance - CCB
string usersTXT = sr.ReadLine();
Reads exactly one line. So you are only checking if you match the first line in the file.
You want File.ReadALlLines (which also disposes the stream correctly, which you aren't):
if (File.ReadAllLines(usersPath).Contains(user_txt.Text))
{
}
That reads all the lines, enumerates them all checking if your line is in the collection. The only downside to this approach is that it always reads the entire file. If you want to only read until you find your input, you'll need to roll the read loop yourself. Do make sure to use the StreamReader in a using block if you take that route.
You can also just use File.ReadLines (thanks #Selman22) to get the lazy enumeration version of this. I would go with this route personally.
Implemenation that shows this at: http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,675b2259e8706c26
if (File.ReadAllLines(path).Any(x => x == line))
{
// line found
}
Replace x == line with a case-insensitive check or Contains if you want.
Try using the Contains() function on the string:
private void acceptBtn_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(usersPath);
string usersTXT = sr.ReadLine();
if (user_txt.Text.Contains(usersTXT))
{
loginPanel.Visible = false;
}
}
I need to perform the following operations with a text file and a List:
Read all lines of text file (non delimited) into a string based list
Whilst the application is open I need to do the following:
Check for instances of a string in the List
Add new entries to the List
Remove all identical instances of a defined string from the List
Write the contents of the List back to the text file including any changes made as soon as they are made
Firstly, how do I read and write between Lists and text files?
Secondly, how do I search a List for a string?
Lastly, how do I safely remove an item out of a List without leaving gaps in the text file I write?
public void homework()
{
string filePath = #"E:\test.txt";
string stringToAdd = "test_new";
IList readLines = new List();
// Read the file line-wise into List
using(var streamReader = new StreamReader(filePath, Encoding.Default))
{
while(!streamReader.EndOfStream)
{
readLines.Add(streamReader.ReadLine());
}
}
// If list contains stringToAdd then remove all its instances from the list; otherwise add stringToAdd to the list
if (readLines.Contains(stringToAdd))
{
readLines.Remove(stringToAdd);
}
else
{
readLines.Add(stringToAdd);
}
// Write the modified list to the file
using (var streamWriter = new StreamWriter(filePath, false, Encoding.Default))
{
foreach(string line in readLines)
{
streamWriter.WriteLine(line);
}
}
}
Try to google before you post the question.
I'd start here:
Read from text file: http://dotnetperls.com/readline
List Actions
1. Removing from a list
2. Searching in a List
Write to a text file: http://www.csharp-station.com/HowTo/ReadWriteTextFile.aspx
I'll just share my idea...
using System.IO;
public void newMethod()
{
//get path of the textfile
string textToEdit = #"D:\textfile.txt";
//read all lines of text
List<string> allLines = File.ReadAllLines(textToEdit).ToList();
//from Devendra's answer
if (allLines.Contains(stringToAdd))
{
allLines.Remove(stringToAdd);
}
else
{
allLines.Add(stringToAdd);
}
//extra: get index and edit
int i = allLines.FindIndex(stringToEdit => stringToEdit.Contains("need to edit")) ;
allLines[i] = "edit";
//save all lines
File.WriteAllLines(textToEdit, allLines.ToArray());
}