.net 我如何读取一个文件,即使得到一个“在使用由另一个进程”异常?

chhkpiq4  于 2023-07-01  发布在  .NET
关注(0)|答案(5)|浏览(124)

在VB.NET或C#中,我试图读取另一个程序正在使用的文本文件的内容(这就是重点,实际上,我不能停止程序或它停止写入文本文件,我想定期读出另一个程序中文本文件中的内容)。
这是我使用的代码(VB.NET)

Dim strContents As String
Dim objReader As StreamReader
objReader = New StreamReader(FullPath)
strContents = objReader.ReadToEnd()
objReader.Close()

在C#中:

var objReader = new StreamReader(FullPath);
var strContents = objReader.ReadToEnd();
objReader.Close();

但是,上面的代码会抛出IO异常“The process cannot access the file 'file.txt' because it is being used by another process.”(进程无法访问文件'file.txt',因为它正被另一个进程使用)。

xam8gpfp

xam8gpfp1#

FileStream logFileStream = new FileStream("c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream);

while (!logFileReader.EndOfStream)
{
    string line = logFileReader.ReadLine();
    // Your code here
}

// Clean up
logFileReader.Close();
logFileStream.Close();

Original source for code

c9x0cxw0

c9x0cxw02#

我来做鱼。FileShare模式非常重要,必须允许写入共享。这是无法拒绝的,因为正在写入文件的进程已经获得了写入权限。StreamReader()构造函数使用FileShare.Read,并且没有使用其他值的选项。使用StreamReader(Stream)构造函数确实是一种解决方法。
但是要注意,这种共享模式也会对您的代码产生影响。您无法预测其他进程何时刷新该文件。您阅读的最后一行可能只包含一行文本的一部分。当它再次刷新文件缓冲区时,稍后,您将获得该行的其余部分。很明显,这会打乱你的逻辑。

nwlls2ji

nwlls2ji3#

这取决于附加到文件的其他应用程序打开文件时使用的FileShare模式。当其他应用程序打开文件时,它为其他应用程序指定了FileShare模式来访问该文件。此FileShare模式可能是读、写、两者、删除、所有这些,或无
您必须指定与其他应用程序指定的FileShare模式完全相同的模式。如果另一个应用程序只允许阅读,使用FileShare.Read;如果它允许读取和写入,使用FileShare.ReadWrite
StreamReader只使用FileShare.Read模式,因此您可以假定这不是正确的模式。所以,试试ReadWrite,像这样:

FileStream fs = new FileStream(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader reader = new StreamReader(fs);
zf2sa74q

zf2sa74q4#

不确定这将如何与一个已经打开的文件,但这将防止您的应用程序锁定它:

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);

希望能帮上忙!

hfwmuf9z

hfwmuf9z5#

我从ChatGPT中撬出了这段代码,它可以工作!首先,我要求C#解决方案,没有运气,然后要求C++,好运,然后要求它在C#中做同样的事情,这里是未触及的代码。编辑:接受的答案也有效,奇怪的是我试过了。

using System;
using System.IO;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CreateFile(
        string lpFileName,
        FileAccess dwDesiredAccess,
        FileShare dwShareMode,
        IntPtr lpSecurityAttributes,
        FileMode dwCreationDisposition,
        FileAttributes dwFlagsAndAttributes,
        IntPtr hTemplateFile
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool ReadFile(
        IntPtr hFile,
        byte[] lpBuffer,
        uint nNumberOfBytesToRead,
        out uint lpNumberOfBytesRead,
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    static void Main()
    {
        IntPtr fileHandle = CreateFile(
            "path/to/file.txt",
            FileAccess.Read,
            FileShare.ReadWrite,
            IntPtr.Zero,
            FileMode.Open,
            FileAttributes.Normal,
            IntPtr.Zero
        );

        if (fileHandle != IntPtr.Zero && fileHandle != new IntPtr(-1))
        {
            try
            {
                FileInfo fileInfo = new FileInfo("path/to/file.txt");
                byte[] buffer = new byte[fileInfo.Length];

                if (ReadFile(fileHandle, buffer, (uint)fileInfo.Length, out uint bytesRead, IntPtr.Zero))
                {
                    string content = System.Text.Encoding.Default.GetString(buffer, 0, (int)bytesRead);
                    Console.WriteLine(content);
                }
            }
            finally
            {
                CloseHandle(fileHandle);
            }
        }
        else
        {
            Console.WriteLine("Failed to open file");
        }
    }
}

相关问题