首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VB Dotnet >

两个程序与此同时对一个文件分别进行读和写操作,能行吗

2012-12-16 
两个程序同时对一个文件分别进行读和写操作,能行吗?我现在需要写一个这样功能的程序(程序A):从另一个程序(

两个程序同时对一个文件分别进行读和写操作,能行吗?
我现在需要写一个这样功能的程序(程序A):从另一个程序(程序B)生成的log文件中读出文件内容。程序B是一直运行的,log文件的内容也是不断增加的,我写的程序A也要一直监视log文件,只要内容一变化,马上就要从文件中读取内容。
我现在担心的是出现log文件只能被一个程序使用,另一个程序打开文件时会失败,被提示文件被占用;
还有个问题就是(在文件能同时被两个程序打开的前提下)我的程序A怎么知道log文件的内容变化了,是否需要先关闭文件再打开啊?还是直接读取文件就能读出更新后的内容?
注意是两个不同的程序,不是两个线程。
急需解决,请高手指教
[最优解释]
建议使用内存共享文件或者管道同步两个进程的数据。
[其他解释]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        // 上次读取行的索引
        static Int32 iLastIndex;

        static void Display(String path)
        {
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    Int32 curIndex = 0;
                    String strText = sr.ReadLine();

                    // 路过已经读取的行
                    while (strText != null && iLastIndex != 0 && curIndex++ < iLastIndex)
                    {
                        strText = sr.ReadLine();
                    }

                    // 显示新增行
                    while (strText != null)
                    {
                        iLastIndex++;
                        Console.WriteLine(strText);
                        strText = sr.ReadLine();
                    }
                }


            }
        }

        static void WriteLog(Object path)
        {
            using (FileStream fs = new FileStream(path.ToString(), FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    while (true)
                    {
                        sw.WriteLine(System.DateTime.Now.ToString());
                        sw.Flush();

                        Thread.Sleep(1000);
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            String strLog = "c:\\1.log";
            ThreadPool.QueueUserWorkItem(new WaitCallback(WriteLog), strLog);

            Thread.Sleep(1000);

            iLastIndex = 0;

            FileWatcher fileWatcher = new FileWatcher(strLog);
            fileWatcher.OnFileChange += Display;
            fileWatcher.Start();

            Console.ReadKey();
        }
    }

    /// <summary>
    /// 监控文件类
    /// </summary>
    class FileWatcher
    {
        /// <summary>
        /// 文件有改变委托
        /// </summary>
        /// <param name="path"></param>
        /// <param name="lineCount"></param>
        public delegate void FileChangeHandler(String path);



        /// <summary>
        /// 文件有改变时触发事件
        /// </summary>
        public event FileChangeHandler OnFileChange;

        /// <summary>
        /// 文件路径
        /// </summary>
        private String _FilePath;

        /// <summary>
        /// 文件大小
        /// </summary>
        private Int64 _FileSize;
        private Int64 _FileLastWriteTime;

        /// <summary>
        /// 监控文件类
        /// </summary>
        /// <param name="path"></param>
        public FileWatcher(String path)
        {
            _FilePath = path;
        }

        /// <summary>
        /// 启动
        /// </summary>
        public void Start()
        {
            if (File.Exists(_FilePath))
            {
                FileInfo fileInfo = new FileInfo(_FilePath);

                _FileLastWriteTime = 0;
                _FileSize = 0;

                ThreadPool.QueueUserWorkItem(new WaitCallback(FileWatchThread), null);
            }
        }

        /// <summary>
        /// 文件监控线程
        /// </summary>
        /// <param name="obj"></param>
        private void FileWatchThread(Object obj)
        {
            while (true)
            {
                FileInfo fileInfo = new FileInfo(_FilePath);

                Int64 lastWrite = fileInfo.LastWriteTime.Ticks;


                Int64 size = fileInfo.Length;

                if (size != 0 && (lastWrite != _FileLastWriteTime 
[其他解释]

引用:
我的程序A怎么知道log文件的内容变化了,是否需要先关闭文件再打开啊?还是直接读取文件就能读出更新后的内容?


文件都有大小和最后修改时间,判断这两个数据和上次不一样的



[其他解释]
事实上管道就很好,而且使用wcf是使用管道进行双工(双向)通讯最简单的办法。
内存映射文件的效率更高。总之建议lz能采用规范的方法,这样在保证可靠性、性能和维护方面会有很多优势。
[其他解释]
假设内容只是增加而不是修改以前的,你只需要在文件头部标记一下我写到多少行去了就是,另一个只需要判定一下这次的行号和上次的行号有啥变化就可以了

当然我这里的前提是“一个只管写,另一个只管读,而且写的只是增量写而做修改删除工作”


[其他解释]
引用:
建议使用内存共享文件或者管道同步两个进程的数据。

内容共享文件要怎么操作啊?
管道同步在两个不同的程序间能实现吗?
[其他解释]
http://msdn.microsoft.com/zh-cn/library/bb546085.aspx
[其他解释]
http://msdn.microsoft.com/zh-cn/library/bb546085.aspx
[其他解释]
http://msdn.microsoft.com/zh-cn/library/dd997372.aspx
这是内存映射文件的教程
[其他解释]
引用:
引用:
我的程序A怎么知道log文件的内容变化了,是否需要先关闭文件再打开啊?还是直接读取文件就能读出更新后的内容?


文件都有大小和最后修改时间,判断这两个数据和上次不一样的


那对新增加的部分内容读取有什么好的方法吗?比如之前已经读了20行的数据,现在新增加了5行数据,我只需要读取这5行的数据,
[其他解释]
引用:
http://msdn.microsoft.com/zh-cn/library/dd997372.aspx
这是内存映射文件的教程


谢谢,我先去看看
[其他解释]
引用:
引用:
引用:
我的程序A怎么知道log文件的内容变化了,是否需要先关闭文件再打开啊?还是直接读取文件就能读出更新后的内容?


文件都有大小和最后修改时间,判断这两个数据和上次不一样的


那对新增加的部分内容读取有什么好的方法吗?比如之前已经读了20行的数据,现在新增加了5行数据,我只需要读取这5行的数据,


Int32 iLastIndex = 20;
这样就行了吧


[其他解释]
引用:
引用:

引用:
引用:
我的程序A怎么知道log文件的内容变化了,是否需要先关闭文件再打开啊?还是直接读取文件就能读出更新后的内容?


文件都有大小和最后修改时间,判断这两个数据和上次不一样的


那对新增加的部分内容读取有什么好的方法吗?比如之前已经读了20行的数据,现在新增加了5行数据,我只需要读取这5行的数据,


I……


有这个属性吗?是通过定义filestream来读还是用的其它的方法?我记得filestream好像没得行号的属性啊。
[其他解释]
caozhy
    你说的两种方法我看了文档了,内存映射我的理解是要文件不变的情况下适用的,也有可能是我理解错误。我的情况是log文件一直在增加内容的。命名管道我觉得也不适合我的情况,我的情况是:程序B是别人已经做好了的,我改不了的。
    谢谢你,
[其他解释]
有没有可能VB.NET其实不用考虑这么多啊,可以两个程序同时操作这个文件啊??
[其他解释]
引用:
有没有可能VB.NET其实不用考虑这么多啊,可以两个程序同时操作这个文件啊??



B程序没有独占日志文件吧?如果独占了,A程序是不能打开的


[其他解释]
引用:
引用:

有没有可能VB.NET其实不用考虑这么多啊,可以两个程序同时操作这个文件啊??


B程序没有独占日志文件吧?如果独占了,A程序是不能打开的


我刚写了两个小程序试了下,在B程序没有向文件写入时,两个程序都能打开,而且A程序还能读出文件内容,但B程序开始写的时候就出错了。以filestream方式打开文件可以设置fileshare属性为readwrite,这样两个程序都可以操作文件了,但这个方式我不知道怎么按行读取内容。
[其他解释]
引用:
我现在需要写一个这样功能的程序(程序A):从另一个程序(程序B)生成的log文件中读出文件内容。程序B是一直运行的,log文件的内容也是不断增加的,我写的程序A也要一直监视log文件,只要内容一变化,马上就要从文件中读取内容。
我现在担心的是出现log文件只能被一个程序使用,另一个程序打开文件时会失败,被提示文件被占用;
还有个问题就是(在文件能同时被两个程序打开的前提下)我的程序A怎么知道l……


不要仅担心,你应该动手写测试程序。

只有代码不骗人。
[其他解释]
引用:
假设内容只是增加而不是修改以前的,你只需要在文件头部标记一下我写到多少行去了就是,另一个只需要判定一下这次的行号和上次的行号有啥变化就可以了

当然我这里的前提是“一个只管写,另一个只管读,而且写的只是增量写而做修改删除工作”


文件内容是只有增加的情况,标记写到多少行也能做到,但下次打开的时候怎么从标记的行开始读取呢?用filestream的方式打开文件可以设置position属性好像能办到,但这种方式好像不支持按行读。用streamreader方式打开文件又不能设置行号了。试了几种方式,好像都没有两者兼具的。
不知道各位有什么好方法啊。
[其他解释]
 size != _FileSize))
                {
                    _FileLastWriteTime = lastWrite;
                    _FileSize = size;

                    // 当文件大小或者最后修改时间有改变时触发事件,通知上层,进行反序列化
                    if (OnFileChange != null)
                    {
                        OnFileChange(_FilePath);
                    }
                }

                Thread.Sleep(2000);
            }
        }
    }
}


必须要有读写权限


热点排行