如何使用.NET以非独占方式打开文件进行写访问

7

在.NET中,是否可以以非独占写访问方式打开文件?如果可以,如何操作?我希望有两个或更多进程可以同时写入同一个文件。

编辑:这是问题的背景:我正在为IIS编写一个简单的日志记录HTTPModule。由于在不同应用程序池中运行的应用程序作为不同的进程运行,因此我需要一种在进程之间共享日志文件的方法。我可以编写复杂的文件锁定例程或惰性写入器,但这是一个丢弃的项目,所以这并不重要。

这是我用来测试该过程的代码。

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

namespace FileOpenTest
{
    class Program
    {
        private static bool keepGoing = true;

        static void Main(string[] args)
        {
            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            Console.Write("Enter name: ");
            string name = Console.ReadLine();
            //Open the file in a shared write mode
            FileStream fs = new FileStream("file.txt", 
                                           FileMode.OpenOrCreate, 
                                           FileAccess.ReadWrite, 
                                           FileShare.ReadWrite);

            while (keepGoing)
            {
                AlmostGuaranteedAppend(name, fs);
                Console.WriteLine(name);
                Thread.Sleep(1000);
            }

            fs.Close();
            fs.Dispose();
        }

        private static void AlmostGuaranteedAppend(string stringToWrite, FileStream fs)
        {
            StreamWriter sw = new StreamWriter(fs);

            //Force the file pointer to re-seek the end of the file.
            //THIS IS THE KEY TO KEEPING MULTIPLE PROCESSES FROM STOMPING
            //EACH OTHER WHEN WRITING TO A SHARED FILE.
            fs.Position = fs.Length;

            //Note: there is a possible race condition between the above
            //and below lines of code. If a context switch happens right
            //here and the next process writes to the end of the common
            //file, then fs.Position will no longer point to the end of
            //the file and the next write will overwrite existing data.
            //For writing periodic logs where the chance of collision is
            //small, this should work.

            sw.WriteLine(stringToWrite);
            sw.Flush();
        }

        private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            keepGoing = false;
        }
    }
}

我猜你的意思是说当你写作时,别人可以阅读它 - 如果想允许多个作者似乎有点奇怪。 - Jeff Yates
4个回答

7

在使用File.Open打开文件时,请使用FileShare枚举。具体来说,请使用FileShare.ReadWrite。


即使使用了FileShare枚举,同一个文件也不能同时被多个进程写入。 - hmcclungiii
1
当然可以。我刚刚做到了。 :) - David Morton

6

FileStream类有一个构造函数,其中包括FileShare等多个选项。

new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);

0
我在procbits.com上找到了一个非常有用的答案:

日志文件生成器:(第一个进程)

static void Main(string[] args) {
    var file = @"C:\logfile.txt";
    var fs = File.Open(file, FileMode.Append, FileAccess.Write, FileShare.Read);
    var sw = new StreamWriter(fs);
    sw.AutoFlush = true;
    sw.WriteLine("some data");
    sw.WriteLine("some data2"); //set breakpoint here

    sw.Close();
}

日志文件阅读器:(第二个进程)
static void Main(string[] args) {
    var file = @"C:\logfile.txt";
    var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    var sr = new StreamReader(fs);

    var l1 = sr.ReadLine();
    var l2 = sr.ReadLine();

    sr.Close();
}

简而言之,这是因为文件共享权限设置正确。

-1

不可能的。了解有关如何将文件读取/写入磁盘的信息。

编辑:由于所有的反对票,我想我需要再解释一下。多个进程在同一时间写入同一个文件是绝对不可能的。当一个进程正在写入时,该文件通常对其他写入者不可用,这意味着其他进程必须等待,直到第一个进程不再写入该文件。


1
我相信提问者想要实际上允许在写入的同时进行读取,而不是多个写入者。 - Jeff Yates
1
我的希望是让两个或更多进程同时写入同一个文件。好吗? - hmcclungiii
这不正确,一个文件同时有多个写入者是完全可能的。所写内容的最终结果是不可预测的,但操作系统肯定会允许它。至于库是否允许,则另当别论... - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接