|
I have created the following code
var filename = "wwwroot/Counter/Counter.txt";
var counterStream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
var reader = new StreamReader(counterStream);
var visits = Convert.ToInt32(reader.ReadLine());
visits = visits + 1;
var writer = new StreamWriter(counterStream);
writer.Write(visits);
counterStream.Dispose(); As you will realise, it is a counter for a website I am building. I am OK down to the line.
visits = visits + 1 Visits does contain one more than is originally stored in Counter.txt. However, the last three lines are not writing anything back to the file. I was expecting it to write a new line in the file, although obviously I want it to replace the original finally. I am at a loss as to why it hasn't. Could someone point me in the right direction, please.
|
|
|
|
|
You need to position the file pointer to the appropriate place, either by reading all of the existing lines (and keeping only the last one), or by using Stream.Seek to reposition the file pointer back to the beginning before the Write.
Cheers,
Mick
------------------------------------------------
It doesn't matter how often or hard you fall on your arse, eventually you'll roll over and land on your feet.
|
|
|
|
|
Counter.txt only contains the one number, the number of visits the site has had. My code reads and updates it OK but the code after that doesn't write it back to replace the one that is there. That's all I want to do; replace the old with the new value.
|
|
|
|
|
xiecsuk wrote: That's all I want to do; replace the old with the new value
In which case you need to Seek the stream pointer back to the beginning of the file before the Write
Cheers,
Mick
------------------------------------------------
It doesn't matter how often or hard you fall on your arse, eventually you'll roll over and land on your feet.
|
|
|
|
|
I am not an expert on C# and the Wrox manual I have called C# 6 and .NET Core 1.0 doesn't describe Seek in the pages describing The StreamWriter Class.
If I try and code
writer.Seek(0); it tells me that 'StreamWriter' does not contain a definition for 'Seek'. I am therefore at a loss as to how to proceed.
|
|
|
|
|
Seek the Stream , not the StreamWriter .
Stream.Seek Method (Int64, SeekOrigin) (System.IO)[^]
const string filename = "wwwroot/Counter/Counter.txt";
using (var counterStream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
int visits;
using (var reader = new StreamReader(counterStream))
{
string line = reader.ReadLine;
int.TryParse(line, out visits);
}
visits = visits + 1;
counterStream.Seek(0L, SeekOrigin.Begin);
using (var writer = new StreamWriter(counterStream))
{
writer.Write(visits);
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I have replaced my code with your code exactly as in your message and I get the following error message:
An exception of type 'System.ObjectDisposedException' occurred in System.IO.FileSystem.dll but was not handled in user code
Additional information: Cannot access a closed file. This occurs on the line counterStream.Seek(0L, SeekOrigin.Begin); . Perhaps this is why my code is not updating the file. Somehow, it also thinks it's closed after the update of visits .
visits has been read and incremented correctly in your code.
|
|
|
|
|
Sorry - I forgot that closing the reader also closes the stream.
Try using a different StreamReader constructor:
using (var reader = new StreamReader(counterStream, System.Text.Encoding.UTF8, true, 4096, true))
The last parameter tells the StreamReader not to close the Stream .
Alternatively, remove the using block for the StreamReader :
var reader = new StreamReader(counterStream);
string line = reader.ReadLine;
int.TryParse(line, out visits);
...
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Everything is now working correctly. Thank you very much Richard. Without your help I wouldn't have got there.
I hate C#. Most of my career I have used Fortran, Microsoft Access and Visual Basic. I am just too old to learn these newfangled languages.
|
|
|
|
|
|
Please see my reply to the first reply to my question.
|
|
|
|
|
Have you read and realized what Midi_Mick has written to you ?
You have to do the following to get the saved Counter :
1.1. Open the File
1.2. Read your Value
1.3. Close the File
And you have to do the following to save the Counter :
2.1. Open the File
2.2. Write your Value
2.3. Close the File
|
|
|
|
|
The problem as I see it is that closing the file half way through the update opens it up for another visitor to start updating it before I have written the updated value from the first visit. This negates the point of having a counter.
|
|
|
|
|
So...not the most performant thing, but this should help avoid concurrency issues.
private static int _count;
private static readonly string _fileName = @"C:\my\file\path\and.name";
private static readonly Object _sync = new Object();
public static void Increment()
{
lock(_sync)
{
_count++;
File.WriteAllText(_fileName, _count.ToString());
}
}
void AppStartEvent()
{
lock(_sync)
{
var seed = File.ReadAllText(_fileName);
int result = 0;
if(int.TryParse(seed,out result))
{
_count = result;
}else{
_count = 0;
}
}
}
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Why?
File.Replace operates at the Windows OS level.
You're not going to find a "simpler", less "contentious" solution.
Been there; done that.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
I thought it would save me typing a similar explanation again, although I suppose I could have cut and pasted most of it and edited it where necessary. Anyway, thank you for taking the time to answer my question. It is now working as required.
|
|
|
|
|
"Cut and paste" what?
I still don't see anything that had a bearing on my original response.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
|
Member 13014278 wrote: I want do the same thing but in desktop. Is it possible?
Yes.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Hi OriginalGriff.
Thank you for the answer.
Can you help me to do this?
|
|
|
|
|
What have you tried?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Hi OriginalGriff.
Thank you. What I did was:
public void ShowCursorLoadImage()
{
Form frm = new Form();
PictureBox pb = new PictureBox() { Image = Image.FromFile(@"C:\Users\bfernandes\Documents\KinectMControl\src\KinectV2MouseControl\bin\Release\Images\lamp1.bmp") };
frm.Cursor = new Cursor(((Bitmap)pb.Image).GetHicon());
frm.WindowState = FormWindowState.Maximized;
frm.TransparencyKey = frm.BackColor = System.Drawing.Color.Turquoise;
frm.FormBorderStyle = FormBorderStyle.None;
frm.ShowDialog();
}
But I want what I sent in link in jquery, but I want in C#. Can you help me?
|
|
|
|
|
You want to drag a picture based on the mouse movement? Draw a picture. Work out what your mouse offset is in that picture. Whenever you move your mouse, reposition the picture taking that offset into account. There, you have everything you need to know to write this for yourself.
This space for rent
|
|
|
|
|
Hi Pete O'Hanlon.
Thank you. Yes, I want drag a picture based on the mouse movement. When I move the mouse I want that an image that I load fix in the position of mouse. Can you help me?
|
|
|
|
|
I already have helped you. I've given you the steps you need to follow. The code isn't that difficult. Why don't you try it? All you need is the mouse coordinates, everything else is just basic maths.
This space for rent
|
|
|
|