C# Continuously Read File

c# continuously read file

You want to open a FileStream in binary mode. Periodically, seek to the end of the file minus 1024 bytes (or whatever), then read to the end and output. That's how tail -f works.

Answers to your questions:

Binary because it's difficult to randomly access the file if you're reading it as text. You have to do the binary-to-text conversion yourself, but it's not difficult. (See below)

1024 bytes because it's a nice convenient number, and should handle 10 or 15 lines of text. Usually.

Here's an example of opening the file, reading the last 1024 bytes, and converting it to text:

static void ReadTail(string filename)
{
using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
// Seek 1024 bytes from the end of the file
fs.Seek(-1024, SeekOrigin.End);
// read 1024 bytes
byte[] bytes = new byte[1024];
fs.Read(bytes, 0, 1024);
// Convert bytes to string
string s = Encoding.Default.GetString(bytes);
// or string s = Encoding.UTF8.GetString(bytes);
// and output to console
Console.WriteLine(s);
}
}

Note that you must open with FileShare.ReadWrite, since you're trying to read a file that's currently open for writing by another process.

Also note that I used Encoding.Default, which in US/English and for most Western European languages will be an 8-bit character encoding. If the file is written in some other encoding (like UTF-8 or other Unicode encoding), It's possible that the bytes won't convert correctly to characters. You'll have to handle that by determining the encoding if you think this will be a problem. Search Stack overflow for info about determining a file's text encoding.

If you want to do this periodically (every 15 seconds, for example), you can set up a timer that calls the ReadTail method as often as you want. You could optimize things a bit by opening the file only once at the start of the program. That's up to you.

How to continuously read files in a folder using C#?

use FileSystemWatcher
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx

FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = Freconfig.GetSamplesFolder();
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = "*.jpg";

// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);

// Begin watching.
watcher.EnableRaisingEvents = true;

before starting watcher, use directorylisting to find all existing files and process them, then use watcher

How to Read a text file continuosuly

You can use FileSystemWatcher to listens to the file system change notifications and raises events when a directory, or file in a directory. If the text is appended in the text file but not modified then you can keep track of line numbers you have read and continue after that when change event is triggered.

private int ReadLinesCount = 0;
public static void RunWatcher()
{
FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = "c:\folder";   
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
           | NotifyFilters.FileName | NotifyFilters.DirectoryName;   
    watcher.Filter = "*.txt";   
    watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;

}

private static void OnChanged(object source, FileSystemEventArgs e)
{
int totalLines - File.ReadLines(path).Count();
int newLinesCount = totalLines - ReadLinesCount;
File.ReadLines(path).Skip(ReadLinesCount).Take(newLinesCount );
ReadLinesCount = totalLines;
}

Read Changes on a text file dynamically c#

Perhaps use the FileSystemWatcher along with opening the file with FileShare (as it is being used by another process). Hans Passant has provided a nice answer for this part here:

var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
using (var sr = new StreamReader(fs)) {
// etc...
}

Have a look at this question and the accepted answer which may also help.

How to monitor Textfile and continuously output content in a textbox?

Check out the System.IO.FileSystemWatcher class:

public static Watch() 
{
var watch = new FileSystemWatcher();
watch.Path = @"D:\tmp";
watch.Filter = "file.txt";
watch.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite; //more options
watch.Changed += new FileSystemEventHandler(OnChanged);
watch.EnableRaisingEvents = true;
}

/// Functions:
private static void OnChanged(object source, FileSystemEventArgs e)
{
if(e.FullPath == @"D:\tmp\file.txt")
{
// do stuff
}
}

Edit: if you know some details about the file, you could handle the most efficent way to get the last line. For example, maybe when you read the file, you can wipe out what you've read, so next time it's updated, you just grab whatever is there and output. Perhaps you know one line is added at a time, then your code can immediately jump to the last line of the file. Etc.

C# - Most effective way to periodically read last part of a file

I think you're looking for this, where offset is going to be how much you want backtrack. Reference: MSDN

using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
fs.Seek(offset, SeekOrigin.End);
}

Now the filestream is pointing to however far back in the file you set 'offset' to be, and you can read from there.

How to Read a text file continuosly using FileShare.ReadWrite mode in C#

Reader will stop at the end and close file (if you keep using in the code).

You can check file size and position reader (configured not to use BOM for Unicode encodings) to last read position via Reader.BaseStream (notice remarks about resetting inner buffers).

Note that both processes need to cooperate in picking open mode as if writer does not allow sharing you will have to read, reopen and seek instead.



Related Topics



Leave a reply



Submit