ir antik
ir antik

Reputation: 11

Read Text File and Update it by C#

I want to read a text file that is constantly changing.

But the first problem is that the file size is too large and hangs the first time And every second of this text file (txt) is changing.

Is not the first time only last 50 lines of the file called? So the program is not stopped

And that it is easier to read and added constantly changing ...

Upvotes: 1

Views: 2522

Answers (4)

Gusdor
Gusdor

Reputation: 14334

This probably doesn't demonstrate exactly the program flow that you need but it does give you reading and writing that wont hang your UI ( asynchronous ). Hopefully you will be able to adapt something that you need.

public class AsyncFileUpdate
{
    object locker = new object();
    public FileInfo File { get; private set; }
    public AsyncFileUpdate(FileInfo file)
    {
        File = file;
    }

    /// <summary>
    /// Reads contents of a file asynchronously.
    /// </summary>
    /// <returns>A task representing the asynchronous operation</returns>
    public Task<string> ReadFileAsync()
    {
        return Task.Factory.StartNew<string>(() =>
            {
                lock (locker)
                {
                    using (var fs = File.OpenRead())
                    {
                        StreamReader reader = new StreamReader(fs);
                        using (reader)
                        {
                            return reader.ReadToEnd();
                        }
                    }
                }
            });
    }
    /// <summary>
    /// write file asynchronously
    /// </summary>
    /// <param name="content">string to write</param>
    /// <returns>A task representing the asynchronous operation</returns>
    public Task WriteFileAsync(string content)
    {
        return Task.Factory.StartNew(() =>
        {
            lock (locker)
            {
                using (var fs = File.OpenWrite())
                {
                    StreamWriter writer = new StreamWriter(fs);
                    using (writer)
                    {
                        writer.Write(content);
                        writer.Flush();
                    }
                }
            }
        });
    }
}

/// <summary>
/// Demonstrates usage
/// </summary>
public class FileOperations
{
    public void ProcessAndUpdateFile(FileInfo file)
    {
        AsyncFileUpdate fu = new AsyncFileUpdate(file); ;
        fu.ReadFileAsync()
            .ContinueWith(p => Process(p.Result))
            .ContinueWith(p => fu.WriteFileAsync(p.Result));
    }

    /// <summary>
    /// does the processing on the file content
    /// </summary>
    /// <param name="content"></param>
    /// <returns></returns>
    string Process(string content)
    {
        throw new NotImplementedException("you do this bit ;)");
    }
}

All this Task business is from the Task Parallel Library - an excellent toolkit for taking the hastle out of parallel and asynchronous programming. http://msdn.microsoft.com/en-us/library/dd537608.aspx

Note: File system access is rather expensive and physically degrading to the storage medium. Are you in control of this file (do you create it)? Updating a file every second is quite prohibitive. If you are worried about the file changing while you are examining it, maybe you need to make a copy of it first?

Upvotes: 0

MrFox
MrFox

Reputation: 5106

Watch the files you are interested in.

static class Program
{
    static long position = 0;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.Path = System.Environment.CurrentDirectory;
        watcher.NotifyFilter = NotifyFilters.LastWrite;
        watcher.Filter = "data.txt"; // or *.txt for all .txt files.
        watcher.Changed += new FileSystemEventHandler(OnChanged);
        watcher.EnableRaisingEvents = true;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public static void OnChanged(object source, FileSystemEventArgs e)
    {
        using (FileStream fileStream = new FileStream("data.txt", FileMode.Open))
        {
            // Using Ron Deijkers answer, skip to the part you din't read.
            fileStream.Seek(position, SeekOrigin.End);

            for (int i = 0; i < fileStream.Length; i++)
            {
                fileStream.ReadByte();
            }
        }
    }
}

Upvotes: 2

Ron Deijkers
Ron Deijkers

Reputation: 3091

Assuming I understood you correctly I think you should reopen the file from time to time to read from it and then use the Seek method of the FileStream.

See: http://msdn.microsoft.com/en-us/library/system.io.filestream.seek.aspx

Each time you read from the file you should store the location up to where you have read the file. When you start reading another chunk you use that offset with the seek method to go the part of the file you haven't read.

This way you read the file in chunks without locking it for too long (and thereby blocking the write operations to it)

A thread (or Timer object) could then read from the file from time to time. Make sure the chunks aren't too large so that you don't lock the file for too long.

Upvotes: 1

Jakub Konecki
Jakub Konecki

Reputation: 46008

For asynchronous reading of the text file try using FileHelpers library

http://filehelpers.sourceforge.net/example_async.html

Upvotes: -1

Related Questions