|
I am trying to implement the unix "tail" command.
Currently, I read a byte at a time until no bytes remain, then I sleep for 1000 milli, then I try to read a byte at a time again.
I've always disliked manually polling. Is there a more efficient way to architect this implementation? I was looking for a unix "select" style function.
Thanks,
-Luther
|
|
|
|
|
Are you talking about 'tail' that writes a certain number of lines from the end of a file? First of all, this is open source so you can see how they do it. Second of all, why are you reading a single byte at a time?! You should be using a buffer, a.k.a. byte[] array. Finally, since 'tail' reads lines, you shouldn't be using buffers anyway, unless you want to parse the line endings which are different from OS to OS (and you should take into account all the different line ends like \n, \r\n, etc., to be compatible with *nix's 'tail').
Also, is this for academic purposes, or do you just need a utility to do so? If the latter is true, just download Cygwin[^] and put the bin directory in the %PATH% environment variable. If has many of these handy *nix utilities and it works great. It's also commonly used to easily port other *nix applications to Win32.
I don't know how 'tail' works exactly, or rather what is the best way to get the last 10 (default; or user-specified) lines. 'head' would obviously be easier! The best thing I could think about is to write a custom queue that only stores 10 lines (or a custom amount), automatically pushing the first one out when a new line is added. When you reach the end of the file, just print-out the queue. Based on some 'tail'-like source I've seen, this is pretty much the way it works (but I couldn't find the actual 'tail' source and don't have the source tarballs or SRPMs on my linux system).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
You are right - but the specific TAIL functionality that I'm trying to implement is the continuous monitoring of a file. For example, as the webserver appends to the log file, I want the new text to appear on the screen.
Originally, I was using ReadLine but it seems to drop the first 4 chars of every read. I started Reading a byte at a time to be more explicit. I am currently using the buffer version of Read (as you suggest, I do in fact, need to differentiate unix and win32 newlines).
So - I am currently spawning a Thread, echoing the entire file to a TextBox, and then sleeping for 1 second. I then try to Read again. Instead of manually polling the file every second, I was wondering if there was a "select" style call that would BLOCK until some event happens to the file (new text was added to the file).
I thought about using ReadBlock, but it seems to return when it reaches the end of the data in the file. I need it to BLOCK if it can't read any more data in - not return. Maybe I'm doing something wrong.
Or, maybe I'm doing it the correct way already. I'll take a look at an open source impl of tail.
Many Thanks,
-Luther
|
|
|
|
|
lutherbaker wrote:
I'm trying to implement is the continuous monitoring of a file.
Look into the FileSystemWatcher component. It won't give you the specific changes, but it will be a good indication that a file has changed and then you can store a pointer and increment that to get the next lines.
lutherbaker wrote:
Originally, I was using ReadLine but it seems to drop the first 4 chars of every read.
What characters are these that are getting skipped? I take it this is just a simple IIS log or something? I've never seen such behavior.
lutherbaker wrote:
I need it to BLOCK if it can't read any more data in - not return.
Perhaps not. The information is written as a unit (i.e., one line) so you can get that and the number of bytes actually read. When the file changes (see above), continue reading the next block at the offset of the original position plus the actual bytes read.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Yes, that is exactly what I'm doing. Tailing a simple webserver's log. Sounds like FileSystemWatcher presents a few new options.
If I can write a small app to predictably generate that odd ReadLine behavior, I will post it here. Otherwise, I'll just assume I was doing something odd.
Thank you again,
-LutherB
|
|
|
|
|
Ok, that works even faster and now I don't have to manually deal with threading.
As a side note, when using ReadLine, I noticed my problem again. Here's what I did:
Open notepad, type a few lines, DO NOT newline, save the file.
The tail callback works perfectly. The new text is echoed to the TextBox (I manually insert a new line since ReadLine stripped it.)
Type in a few more characters and save again (still, never typing a newline).
The tail callback misses the first two chars!!
So, I opened cygwin - and got the same behavior!!!
As I believe you explained, tail is reading a line at a time. When I don't type a newline and simply save new text into the file - expecting it to be echoed, it doesn't pick up the first two chars (something do to with expectation of \r\n I would guess).
If I DO type a newline and then save, the following text is read correctly from the first char.
So, that means ReadLine works just fine for what I'm doing - which further simplifies this.
Thanks,
-Luther
One last tidbit, I've implemented native calls to scroll the screen with line appended. Unfortunately, its possible these windows won't have focus when they are tailing files - and it seems that the built in TextBox/RichTextBox must have focus and move manually move the caret and then must scroll to the caret. Awfully cumbersome.
I've wrapped the calls in a class, but they are similar to this:
public readonly uint EM_LINESCROLL = 0x00B6;
public readonly uint EM_GETFIRSTVISIBLELINE = 0x00CE;
public readonly uint EM_GETLINECOUNT = 0x00BA;
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lparam);
private void button1_Click(object sender, System.EventArgs e)
{
int line = SendMessage(richTextBox1.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
int linecount = SendMessage(richTextBox1.Handle, EM_GETLINECOUNT, 0, 0);
SendMessage(richTextBox1.Handle, EM_LINESCROLL, 0, (uint)(linecount - line - 2));
}
Oddly, TextBox scrolls one line at at time. RichTextBox scrolls a page at a time ... unusable for what I'm doing.
|
|
|
|
|
iam making a program in c# to dial to net, i use visual c++ & winAPI like Internetdial() to connect with default connection and numbers from database,but i have a problem internetDial force aform that making a connection the problem that this form sometimes appear and others no action happened so it make my code unuseful
please any help
|
|
|
|
|
This again! Didn't I already tell you that it's obvious to everyone here that we either can't or don't want to help you?
RTFM! Read the docs! Lookup InternetDial in the MSDN Library and sync the TOC to find what other methods are available. Remember that part of R&D is Research - so figure it out. That's how I found the function InternetDial that I originally gave you. Becoming familar with the SDKs helps to have some idea of what you're looking for.
If you're having problems with the form that is supposed to come up upon dialing, this could be a thread issue. Do not open forms on separate threads that are not the main UI thread - the thread on which the application was started.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Hello guys!
I use MS Visual Studio 2003.
So I wanna Filter a DataGrid for example by the first column, only display rows
where the first column = 1.
Maybe my question seems naughty, i swear ive tried to find something about that
but found almost nothing in my msdn(something about datatable.select, but that's filter doesnt
seem usuable for me). So i'd like to find a quiet fast and elegance way to do that.
Is there any?
|
|
|
|
|
//Create The DataView that references the table that contains your data
System.Data.DataView myDataView = new DataView();
myDataView.Table = dataset.tables["myTable"];
//Apply the filter
myDataView.RowFilter = "[First Column] = 1";
//Bind the dataview to your datagrid
myDataGrid.DataSource = myDataView;
myDataGrid.DataBin();
I hope that helps.
|
|
|
|
|
Or...
dataset.Tables["TableName"].DeafultView.RowFilter = "Column1 = 'hello'";
Mazy
No sig. available now.
|
|
|
|
|
Thanks a lot for both of You!!!
It works
|
|
|
|
|
Hello every body and Happy New Year
I am intended to develop a software (windows application with C#) that can coonnect to the internet. In my software i want to restriction on site access and file download. I want to prevent some users to access certain sites or downlaod certain files.
I searched alote but with no benifits or my searh was not strong. I found somethings but some are web applications and the other are methods or classes stands alone, i could not combine them (
if someone can help me?
Thak you
|
|
|
|
|
|
Can any one tell me how i can make a rounded form, also ineed aqua buttons on rounded shapes
|
|
|
|
|
Could try FormShaper and SkinButton from SpringSys.
Their site is http://www.springsys.com
|
|
|
|
|
|
Hi all and happy christmas and New year...
I am developing a c# windows form application in which I need to persist data, that is save data. I want to know what my choices are in this other than using SQL SERVER 2000, which i am using now but I do not want to have my users deploy SQL server on their machines so I wanna change my storage scheme.
What are my choices?
any links would be appreciated.
If I have classes for my Objects, How can I use those classes to store my data on disk. What interfaces should i inherit and implement
what if I want to do my own Indexes on data, say using HAsh tables or B-TREES
THANKS FOR ANY HELP
----------------
Mohsen from IRAN
|
|
|
|
|
If you want your application to work only on desktop and not in a network,MS ACCESS is very good,other databases need somethings to install on user machines like SQLServer. You can import your tables and datas from SQL into ACCESS with IMPORT AND EXPORT DATA WIZARD. Access only have one file so it is easy to back up from it or move it from different machines.
Mazy
No sig. available now.
|
|
|
|
|
thanks for the reply
now, what are my options if I do not wanna use access, or any database for that matter. also take into account that I need to store Persian scripts, ie unicode
Thanks again
Mohsen from Iran
|
|
|
|
|
Look into serialization in .NET, either using the System.Runtime.Serialization namespace elements, or the System.Xml.Serialization namespace elements. The first is true serialization and can handle cirucular references, as well as be easily controlled by implementing ISerializable . All that is required to serialize a Type is attribute it with the SerializableAttribute (put [Serializable] on the class definition). See the .NET Framework SDK documentation for more details, or search this site for plenty of examples (or google). If a Type isn't serializable and you can't / don't want to extend it and attribute it / customize serialization, you can use an ISerializationSurrogate to serialization the Type. You can also fix-up data after serialization is completely by having your object implement IDeserializationCallback . You can serializate to XML (SOAP) or binary with the default formatters. More might exist, or you can (though not recommended, especially without knowing the internals of serialization) implement your own formatter.
XML Serialization, in contrast, using simple attributes and serialization to XML the way you define, unlike SOAP serialization above that would be pretty much unreadable to most people. XML serialization is limited however. You're not technically supposed to be able to control it as much, but you can implement the undocumented IXmlSerializable interface to serialization Types without XML Serialization attributes. This can serialize "prettier" documents, but doesn't have near the capabilities (like handling cirucular references).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Hi
I have a code which prints to the printer using the PrintDocument & PrintPreviewDialog classes.
I need to specify at run time which paper size I want to use: A4, Letter, A3 etc. These are not custome sizes but rather standard sizes, listed in the PaperKind enum.
How can I force a certain paper size at run time? The PaperSize.Kind property is read only.
I tried using the PageSetupDialog too, hoping that I could simply pass it the requierd page size without having to display the dialog, but could not make it work.
thanks
|
|
|
|
|
Again, as I recommended before - and as MSDN recommends - enumerate the PrintDocument.PrinterSettings.PaperSizes (one the PrintDocument.PrinterSettings.PrinterName is set to the desired printer). If you look at the documentation for PrintDocument , the best place to set the PaperSize is in the handler for the PrintDocument.QueryPageSettings event, which occurs before each PrintDocument.PrintPage event:
private PaperSize paperSize;
private PaperSize GetPaperSize(PrinterSettings printer, PaperKind kind)
{
if (printer == null) throw new ArgumentNullException("printer");
if (this.paperSize == null)
{
foreach (PaperSize size in printer.PaperSizes
{
if (size.Kind == kind)
{
this.paperSize = size;
return this.paperSize;
}
}
}
else return this.paperSize;
throw new ArgumentException("The requested paper size is not supported " +
"by this printer.", "kind");
}
private void printDocument_QueryPageSettings(object sender,
QueryPageSettingsEventHandler e)
{
try
{
e.PageSettings.PaperSize =
this.GetPaperSize(e.PageSettings.PrinterSettings, PaperKind.A3);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Could not print the document: {0}",
ex.Message), "Print Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
e.Cancel = true;
}
} This should work; if not, read the documentation for PrintDocument , PageSettings , and PrinterSettings .
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
|
Hello
I ned create a form dynamically from an XML document, the xml file must contain the control type, the variable name asociated to this control, ..., i.e.
<Parameter>
<Param name="Age">
<ControlType>Editbox</ControlType>
<Desc>Client age</Desc>
<Type>Integer</Type>
<Min>21</Min>
<Max>40</Max>
<Value>25</Value>
</Param>
</Parameter>
Please help me
|
|
|
|
|