I am sending and receiving data using COM port (serial). I have written the following code. This is actually my first C# project as I am kinda new to it. I am trying to write the received data to the text file on my desktop, the program actually creates the file but writes nothing in it. Similarly, I am able to see the received data on the console but it is not being written to the text file. Any help on what I am doing wrong will be much appreciated.
Thank you. The code is below.
class Program
{
SerialPort p = new SerialPort("COM7", 300, Parity.None, 8, StopBits.One);
string sbuffer = string.Empty;
byte i = 0;
static void Main(string[] args)
{
new Program();
}
Program()
{
string[] names = SerialPort.GetPortNames();
Console.WriteLine("Serial ports:");
foreach (string name in names)
{
Console.WriteLine(name);
}
Console.WriteLine("Using COM7");
p.Open();
string data_ = "$1RB\r";
Console.WriteLine("Writing data: {0}",data_);
p.Write(data_);
p.DataReceived += new SerialDataReceivedEventHandler(p_DataReceived);
Console.ReadKey();
p.Close();
}
void p_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(5);
sbuffer += (sender as SerialPort).ReadExisting();
i++;
if (i > 9)
{
Console.WriteLine(sbuffer);
System.IO.File.WriteAllText(#"C:\Users\myname\Desktop\WriteText.txt", sbuffer);
sbuffer = string.Empty;
}
}
}
}
You could use events, or simply use this method and pass your data string to it. It will simply append to the file as long as it exists, or create a new file if it does not. The data written should be identical to whatever output is appearing in your console screen.
static void WriteOutputToTextFile(string _data)
{
string FolderName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //set destination as your desktop
using (StreamWriter SW = new StreamWriter(FolderName + "\\test.txt", true)) //true makes it append to the file instead of overwrite
{
SW.WriteLine(_data);
SW.Close();
}
}
You are opening and overwriting the same file again and again. Use the FileStream (or even better, StreamWriter) class instead, keep the stream open together with the serial port and close it when you're done.
Also, if you transmit text via the serial port, you might want to consider the SerialPort.ReadLine() method that is much easier to use.
Extending #Alan's answer, you can use File.AppendAllText instead of File.WriteAllText which will overwrite the file again and again. So if you receive empty text before you check the file, the file will be overwritten with empty text.
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 am new to programming and I have a question. If I have two functions, one creates a text file and writes into it, while the other opens the same text file and reads from it.
The error I get is:
System.IO.IOException: 'The process cannot access the file '#.txt'
because it is being used by another process.'
I have tried setting seperate timers to each of the functions but it still does not work. I think the best way would be that the function two does not start until function one ends.
Can you help me achieve this?
Thank you very much!
Mike
Source code:
public Form1() {
InitializeComponent();
System.Timers.Timer timerButtona1 = new System.Timers.Timer();
timerButtona1.Elapsed += new ElapsedEventHandler(tickTimera1);
timerButtona1.Interval = 3003;
timerButtona1.Enabled = true;
}
private async void tickTimera1(object source, ElapsedEventArgs e) {
function1();
function2();
}
void function1() {
List<string> linki = new List<string>();
linki.Add("https://link1.net/");
linki.Add("https://link2.net/");
linki.Add("https://link3.net/");
List<string> fileNames = new List<string>();
fileNames.Add("name1");
fileNames.Add("name2");
fileNames.Add("name3");
for (int x = 0; x < fileNames.Count; x++) {
GET(linki[x], fileNames[x]);
//System.Threading.Thread.Sleep(6000);
}
}
async void GET(string link, string fileName) {
var ODGOVOR = await PRENOS_PODATKOV.GetStringAsync(link);
File.WriteAllText(#"C:\Users\...\" + fileName + ".txt", ODGOVOR);
}
void function2() {
string originalText = File.ReadAllText(#"C:\Users\...\fileName.txt", Encoding.Default);
dynamic modifiedText = JsonConvert.DeserializeObject(originalText);
//then i then i read from the same text files and use some data from it..
}
You will have to close the file after editing it.
var myFile = File.Create(myPath);
//myPath = "C:\file.txt"
myFile.Close();
//closes the text file for eg. file.txt
//You can write your reading functions now..
After closing it you can again use it(for reading)
The issue is sometimes file locks don't get released immediately after they are closed.
You can try run a loop to read the file. Inside the loop put a try catch statement and if the file reads successfully break from the loop. Otherwise, wait a few milliseconds and try to read the file again:
string originalText = null;
while (true)
{
try
{
originalText = File.ReadAllText(#"C:\Users\...\fileName.txt", Encoding.Default);
break;
}
catch
{
System.Threading.Thread.Sleep(100);
}
}
after writing your text file, you should close it first before proceeding to your second function:
var myFile = File.Create(myPath);
//some other operations here like writing into the text file
myFile.Close(); //close text file
//call your 2nd function here
Just to elaborate:
public void Start() {
string filename = "myFile.txt";
CreateFile(filename); //call your create textfile method
ReadFile(filename); //call read file method
}
public void CreateFile(string filename) {
var myFile = File.Create(myPath); //create file
//some other operations here like writing into the text file
myFile.Close(); //close text file
}
public void ReadFile(string filename) {
string text;
var fileStream = new FileStream(filename, FileMode.Open,
FileAccess.Read); //open text file
//vvv read text file (or however you implement it like here vvv
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
text = streamReader.ReadToEnd();
}
//finally, close text file
fileStream.Close();
}
The point is, you have to close the FileStream after you are done with any operations with your file. You can do this via myFileStream.Close().
Moreover, File.Create(filename) returns a FileStream object which you can then Close().
Actually this is not a problem of closing/disposing the stream, File.WriteAllText and File.ReadAllText does that internally.
The issue is because a wrong use of the async/await pattern.
GET is async but never awaited, thus causing function1 to finish and move on to function2 before all content was actually written to the file.
The way it is written GET is not awaitable because it is async void which should never be used unless you're dealing with event or really know what you're doing.
So, either remove the use of async/await completely or be async all the way:
Change GET to be awaitable:
async Task GET(string link, string fileName)
await it in the now async function1:
async Task function1()
{
...
for (int x = 0; x < fileNames.Count; x++)
{
await GET(linki[x], fileNames[x]);
//System.Threading.Thread.Sleep(6000);
}
...
await function1 in the Elapsed event:
private async void tickTimera1(object source, ElapsedEventArgs e)
{
await function1();
function2();
}
Create a file and then close it. After can save data into that file.
I did as below.
if (!File.Exists(filePath))
{
File.Create(filePath).Close();
}
File.WriteAllText(filePath, saveDataString)
In one of the unit tests, I had to create a temp file and then remove it after, and I was getting the above error.
None of the answers worked.
Solution that worked was:
var path = $"temp.{extension}";
using (File.Create(path))
{
}
File.Delete(path);
I am working on making a program that is going to read xy coordinates in a text file from a drawing application. I am thinking that the sets of coordinates will start getting detected from the start to the end of the drawn line. For each line drawn there is gonna be a new set of xy coordinates. Then I want to make a program that is
Going to look for updated sets of xy coordinates every x seconds
If the text file is updated I want the new contents of the text file to be written in the console
If the file is not yet updated I don't want it to do anything
Also I am wondering if the best thing is to
Have a single text file that get its contents changed with the new set of xy coordinates?
Or to have a single text file that get the new set of xy coordinates addes to the previous sets of coordinates?
Or have a new text file to be created for every new set of xy coordinates?
I am really new to programming and would really appreciate if I got some kind of help. I have been programming in C# in Visual Studio. I am pretty sure I need to use FileSystemWatcher, I just don't know how to use it....
So far I have only done this:
class Test
{
public static void Main()
{
while (true)
{
try
{
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
catch (Exception e)
{
Console.WriteLine("This file doesn't excist:");
Console.WriteLine(e.Message);
}
Thread.Sleep(2000);
}
}
}
Initialize a watcher as follows:
FileSystemWatcher watcher = new FileSystemWatcher(_folder_name_)
{
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size
};
watcher.Changed += watcher_Changed;
watcher.EnableRaisingEvents = true;
Event handler:
void watcher_Changed(object sender, FileSystemEventArgs e)
{
if (e.Name == "TestFile.txt")
using (StreamReader sr = new StreamReader(e.FullPath))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
Alternative way is to use a System.Threading.Timer.
If a text is appended to the file incrementally, I recommend you to use database, sockets etc instead of file.
Thank you so much for the quick answer and the help! :)
Just before I saw your answer I was working on another way of doing it. The text file will be read and written to the console when the text file exists. When it's read it will be deleted and are waiting for another text file to appear (another set of xy-coordinates). I am not going to have the program to write "Waiting for new file..." in the end, it's just to see that things are working the way I've been thinking. Also I think the Web application need to receive some kind of a message that the text file is read and is now ready to receive a new text file.
Any thoughts if this is an OK way of doing it too?
class Testing
{
public static void Main()
{
string fileName = "TestFile.txt";
while (true)
{
if(File.Exists(fileName))
{
using (StreamReader sr = new StreamReader(fileName))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
else
{
Console.WriteLine("Waiting for new file...");
}
File.Delete(fileName);
Thread.Sleep(5000);
}
}
}
Since I'm new, I'm just asking to be sure. I don't know what is going to work out the best when it comes to every part of the system working together. At least I have two ways to work with now! :D
I am making simple tool for manipulating images in a database. I want to show the output result in a txt file and because the outcome may be different each time, I want the file to be rewritten with the fresh data every time the data is executed.
Also I want (if possible) to use some default location where the txt file will be created even though I have an App.Config file and that's also an option.
The problem I am having is with this code:
string Resultfile =
System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
"\\PictureStatus.txt";
FileStream strm = new FileStream(Resultfile , FileMode.Create);
TextWriter tw = new StreamWriter(strm);
This populates the PictureStatus.txt only once and then I get the same text over and over again. I noticed that if I use some random destination the file is updated. Not sure if it's just random behavior or have something to do with using MyDocuments, but what I need is a way to be sure that I'll rewrite the file with the new data each time, and if possible, use some default destination that will work for other people.
You can try something like this
public partial Form2 : Form
{
public string path = Environment.CurrentDirectory + "/" + "Name.txt";
public Form2()
{
InitializeComponent();
if (!File.Exists(path))
{
File.Create(path);
}
}
private void button2_Click(object sender, EventArgs e)
{
using (StreamWriter sw = new StreamWriter(path, true))
{
sw.WriteLine("This text will be writen in the txt file", true);
sw.Close();
}
}
}
I have add to the button, when I pressed it will be written in the next line every time. If you remove "true" from code, it will be overwritten every time.
I am able to do read/write/append operation on text file storing in isolated storage in WP7 application.
My scenario is that I am storing space seperated values in text file inside isolated storage.
So if I have to find for some particular line having some starting key then how to overwrite
value for that key without affecting the other line before and after it.
Example:
Key Value SomeOtherValue
*status read good
status1 unread bad
status2 null cantsay*
So if I have to change the whole second line based on some condition with key as same
status1 read good
How can I achieve this?
There are a number of ways you could do this, and the method you choose should be best suited to the size and complexity of the data file.
One option to get you started is to use the static string.Replace() method. This is crude, but if your file is only small then there is nothing wrong with it.
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("*status read good");
sb.AppendLine("status1 unread bad");
sb.AppendLine("status2 null cantsay*");
string input = sb.ToString();
var startPos = input.IndexOf("status1");
var endPos = input.IndexOf(Environment.NewLine, startPos);
var modifiedInput = input.Replace(oneLine.Substring(startPos, endPos - startPos), "status1 read good");
Console.WriteLine(modifiedInput);
Console.ReadKey();
}
}
If you store this information in text files then there won't be a way around replacing whole files. The following code does exactly this and might even be what you are doing right now.
// replace a given line in a given text file with a given replacement line
private void ReplaceLine(string fileName, int lineNrToBeReplaced, string newLine)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
// the memory writer will hold the read and modified lines
using (StreamWriter memWriter = new StreamWriter(new MemoryStream()))
{
// this is for reading lines from the source file
using (StreamReader fileReader = new StreamReader(new IsolatedStorageFileStream(fileName, System.IO.FileMode.Open, isf)))
{
int lineCount = 0;
// iterate file and read lines
while (!fileReader.EndOfStream)
{
string line = fileReader.ReadLine();
// check if this is the line which should be replaced; check is done by line
// number but could also be based on content
if (lineCount++ != lineNrToBeReplaced)
{
// just copy line from file
memWriter.WriteLine(line);
}
else
{
// replace line from file
memWriter.WriteLine(newLine);
}
}
}
memWriter.Flush();
memWriter.BaseStream.Position = 0;
// re-create file and save all lines from memory to this file
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(fileName, System.IO.FileMode.Create, isf))
{
memWriter.BaseStream.CopyTo(fileStream);
}
}
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ReplaceLine("test.txt", 1, "status1 read good");
}
And I agree with slugster: using SQLCE database might be a solution with better performance.