我想阅读一个不断变化的文本文件。
但第一个问题是文件太大而且第一次挂起 而且这个文本文件(txt)的每一秒都在变化。
是不是第一次只调用该文件的最后50行?所以程序没有停止
而且更容易阅读和不断变化......
答案 0 :(得分:2)
Watch您感兴趣的文件。
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();
}
}
}
}
答案 1 :(得分:1)
假设我理解正确,我认为您应该不时重新打开该文件,然后使用FileStream的Seek方法。
请参阅:http://msdn.microsoft.com/en-us/library/system.io.filestream.seek.aspx
每次从文件中读取时,都应将位置存储到读取文件的位置。当您开始阅读另一个块时,您使用该方法使用该偏移量来获取您尚未阅读的文件部分。
这样你就可以在没有长时间锁定文件的情况下读取文件(从而阻止对它的写入操作)
然后,线程(或Timer对象)可以不时从文件中读取。确保块不是太大,以免您长时间锁定文件。
答案 2 :(得分:0)
这可能并不能完全展示您需要的程序流程,但它确实会让您阅读和编写不会挂起您的UI(异步)。希望你能够适应你需要的东西。
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 ;)");
}
}
所有这些Task
业务来自任务并行库 - 一个出色的工具包,用于解决并行和异步编程问题。 http://msdn.microsoft.com/en-us/library/dd537608.aspx
注意:文件系统访问相当昂贵,并且物理上会降级到存储介质。你是否控制了这个文件(你创建它)吗?每秒更新一个文件是非常令人望而却步的。如果您在检查文件时担心文件更改,可能需要先复制一份文件吗?
答案 3 :(得分:-1)
要异步读取文本文件,请尝试使用 FileHelpers 库