如何打开文件以便安全地允许其他程序读取?

时间:2016-01-29 12:13:05

标签: c# .net io filestream

我打开一个FileStream并使用以下两个代码片段为其写行:

public static System.IO.FileStream OpenFileStream(string FullFilename) {
    return new System.IO.FileStream(FullFilename, System.IO.FileMode.OpenOrCreate,
        System.IO.FileAccess.ReadWrite, System.IO.FileShare.Read);
}

public static void WriteLine(System.IO.FileStream fileStream, string str) {
    fileStream.Seek(0, System.IO.SeekOrigin.End);
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str + "\r\n");
    fileStream.Write(bytes, 0, bytes.Length);
    fileStream.Flush();
}

正在访问的文件,即FullFilename中的OpenFileStream参数,是一个CSV文件。文件打开后,要求能够查看到目前为止已经写入CSV文件的内容。

我一直在使用Microsoft Excel,当Excel打开文件时,它会注意到该文件正在使用中并给我一个对话框,告诉我我只能获得只读访问权限。尽管如此,Excel尝试打开文件的行为有时会导致异常被抛出到已打开FileStream的程序中,即使OpenFileStream授予其他程序的访问权限为System.IO.FileShare.Read

抛出的异常是带有System.IO.IOException消息的The process cannot access the file because another process has locked a portion of the file,并且可以在访问WriteLine的{​​{1}}函数中的任何位置抛出它。 / p>

如何防止Excel尝试读取文件等其他程序抛出任何异常?

2 个答案:

答案 0 :(得分:0)

您每次都在为文件末尾写一个字符串。为了防止“唠叨”每次写入文件时都可以关闭文件的文件。

StreamWriter的默认编码为UTF8

public static void WriteLine(string fileName, string str) 
{
    using (FileStream fs = new FileStream(fileName,FileMode.Append, FileAccess.Write, FileShare.Read))
    using (StreamWriter sw = new StreamWriter(fs))
    {
        sw.WriteLine(str);
    }
}

答案 1 :(得分:0)

感谢@ i486的线索。这个版本的WriteLine 似乎来解决问题:

    public static void WriteLine(System.IO.FileStream fileStream, string str) {
        try {
            LockFile(fileStream);
            fileStream.Seek(0, System.IO.SeekOrigin.End);
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str + "\r\n");
            fileStream.Write(bytes, 0, bytes.Length);
            fileStream.Flush();
        } finally {
            UnlockFile(fileStream);
        }
    }
    public static void LockFile(System.IO.FileStream fileStream) {
        bool notlocked = true;
        while (notlocked) {
            try { fileStream.Lock(0, long.MaxValue); notlocked = false; } catch (Exception Ex) { ReaperCore.CoreLogging.ExceptionDescription(Ex); }
        }
    }
    public static void UnlockFile(System.IO.FileStream fileStream) { fileStream.Unlock(0, long.MaxValue); }

剩下的问题是如何处理文件被读取访问权限保持文件锁定的可能性,因为如果发生这种情况,上面的代码将永远保留在LockFile(...)