Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. FileStream question

FileStream question

Scheduled Pinned Locked Moved C#
csharpc++sysadminhelpquestion
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tim Kohler
    wrote on last edited by
    #1

    I'm trying to open a file for writing in a server process. I do not want any other process to be able to write to the file while I have it open, but I do want to allow other programs to read from it. Seems simple enough. I think I've done this with CFile in MFC. I'm getting a problem trying to use the .NET FileStream class. Can any of you shed light on why I'm getting a 'File is in use' IO exception with this: try { String Nm = "c:\\testfile.txt"; //simulate the server opening the file for writing: FileStream str = File.Open(Nm, FileMode.Append, FileAccess.Write, FileShare.Read); //simulate some other process opening the file for reading: (exception thrown here) FileStream sss = File.OpenRead(Nm); } catch (IOException e) { System.Console.WriteLine(e.Message); }

    H 1 Reply Last reply
    0
    • T Tim Kohler

      I'm trying to open a file for writing in a server process. I do not want any other process to be able to write to the file while I have it open, but I do want to allow other programs to read from it. Seems simple enough. I think I've done this with CFile in MFC. I'm getting a problem trying to use the .NET FileStream class. Can any of you shed light on why I'm getting a 'File is in use' IO exception with this: try { String Nm = "c:\\testfile.txt"; //simulate the server opening the file for writing: FileStream str = File.Open(Nm, FileMode.Append, FileAccess.Write, FileShare.Read); //simulate some other process opening the file for reading: (exception thrown here) FileStream sss = File.OpenRead(Nm); } catch (IOException e) { System.Console.WriteLine(e.Message); }

      H Offline
      H Offline
      Heath Stewart
      wrote on last edited by
      #2

      Actually, you're aren't opening it in a different process so it's not a good test. According to the documentation for the FileShare enum, the file has to be opened in a different process or in a different thread. I tried your code and, of course, got the same error. I open the file in a separate thread and it works fine. Also, pay attention to my finally block in the code below. You should use the finally block in a try-catch (or forget the catch if you want the exception to be thrown to the caller) to make sure things are cleaned up, whether or not an exception is thrown, or even return is called (it is not executed only when the CLR is unloaded, like calling Environment.Exit):

      // FileTest.cs
      using System;
      using System.IO;
      using System.Threading;

      public class FileTest
      {
        public static void Main()
        {
          FileStream s = null;
          try
          {
            s = File.Open("FileTest.cs", FileMode.Open,
              FileAccess.ReadWrite, FileShare.Read);
            new Thread(new ThreadStart(ReadFile)).Start();
          }
          catch (Exception e)
          {
            Console.Error.WriteLine(e.Message);
          }
          finally
          {
            if (s != null) s.Close();
          }
        }

      private static void ReadFile()
        {
          FileStream s = null;
          try
          {
            s = File.OpenRead("FileTest.cs");
            Stream os = Console.OpenStandardOutput(4096);
            int read = 0;
            byte[] buffer = new byte[4096];
            do
            {
              read = s.Read(buffer, 0, buffer.Length);
              os.Write(buffer, 0, read);
            } while (read == buffer.Length);
          }
          catch (Exception e)
          {
            Console.Error.WriteLine(e.Me

      T 1 Reply Last reply
      0
      • H Heath Stewart

        Actually, you're aren't opening it in a different process so it's not a good test. According to the documentation for the FileShare enum, the file has to be opened in a different process or in a different thread. I tried your code and, of course, got the same error. I open the file in a separate thread and it works fine. Also, pay attention to my finally block in the code below. You should use the finally block in a try-catch (or forget the catch if you want the exception to be thrown to the caller) to make sure things are cleaned up, whether or not an exception is thrown, or even return is called (it is not executed only when the CLR is unloaded, like calling Environment.Exit):

        // FileTest.cs
        using System;
        using System.IO;
        using System.Threading;

        public class FileTest
        {
          public static void Main()
          {
            FileStream s = null;
            try
            {
              s = File.Open("FileTest.cs", FileMode.Open,
                FileAccess.ReadWrite, FileShare.Read);
              new Thread(new ThreadStart(ReadFile)).Start();
            }
            catch (Exception e)
            {
              Console.Error.WriteLine(e.Message);
            }
            finally
            {
              if (s != null) s.Close();
            }
          }

        private static void ReadFile()
          {
            FileStream s = null;
            try
            {
              s = File.OpenRead("FileTest.cs");
              Stream os = Console.OpenStandardOutput(4096);
              int read = 0;
              byte[] buffer = new byte[4096];
              do
              {
                read = s.Read(buffer, 0, buffer.Length);
                os.Write(buffer, 0, read);
              } while (read == buffer.Length);
            }
            catch (Exception e)
            {
              Console.Error.WriteLine(e.Me

        T Offline
        T Offline
        Tim Kohler
        wrote on last edited by
        #3

        Thanks for the quick response Heath. Try adding a Thread.Sleep after you start that other thread so that the original thread still has the file open for writing. Before moving my stuff to the over simple example I submitted, I had it in different programs altogther. Any other suggestions? I tried the exact same thing with CFile and it works: try { //open for exclusive write CStdioFile file; BOOL bOpen1 = file.Open("C:\\timtest2.txt", CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite); file.WriteString("hi"); file.Flush(); //open a reader CStdioFile f2; BOOL bOpen2 = f2.Open("c:\\timtest2.txt", CFile::modeRead | CFile::shareDenyNone); CString str; f2.ReadString(str); //try to open another writer --- this open fails CStdioFile file3; BOOL bOpen3 = file3.Open("C:\\timtest2.txt", CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite); file3.WriteString("hi"); file3.Flush(); } catch (CFileException* pe) { pe->ReportError(); pe->Delete(); } Argh!!

        H 1 Reply Last reply
        0
        • T Tim Kohler

          Thanks for the quick response Heath. Try adding a Thread.Sleep after you start that other thread so that the original thread still has the file open for writing. Before moving my stuff to the over simple example I submitted, I had it in different programs altogther. Any other suggestions? I tried the exact same thing with CFile and it works: try { //open for exclusive write CStdioFile file; BOOL bOpen1 = file.Open("C:\\timtest2.txt", CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite); file.WriteString("hi"); file.Flush(); //open a reader CStdioFile f2; BOOL bOpen2 = f2.Open("c:\\timtest2.txt", CFile::modeRead | CFile::shareDenyNone); CString str; f2.ReadString(str); //try to open another writer --- this open fails CStdioFile file3; BOOL bOpen3 = file3.Open("C:\\timtest2.txt", CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite); file3.WriteString("hi"); file3.Flush(); } catch (CFileException* pe) { pe->ReportError(); pe->Delete(); } Argh!!

          H Offline
          H Offline
          Heath Stewart
          wrote on last edited by
          #4

          Good point - hadn't thought of that. :-O Have you tried accessing the file from two different processes? I mean, I would think the same process could access it, but maybe there is a problem related to that.

          -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

          T 1 Reply Last reply
          0
          • H Heath Stewart

            Good point - hadn't thought of that. :-O Have you tried accessing the file from two different processes? I mean, I would think the same process could access it, but maybe there is a problem related to that.

            -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

            T Offline
            T Offline
            Tim Kohler
            wrote on last edited by
            #5

            Well I originally coded it in two processes and that's when I noticed the problem to begin with. The weird thing is that other applications (notepad) can open the files (and they come up in readonly like I would expect). I'm totally stumped on what's wrong. I really don't want to do interop for something so silly.

            T 1 Reply Last reply
            0
            • T Tim Kohler

              Well I originally coded it in two processes and that's when I noticed the problem to begin with. The weird thing is that other applications (notepad) can open the files (and they come up in readonly like I would expect). I'm totally stumped on what's wrong. I really don't want to do interop for something so silly.

              T Offline
              T Offline
              Tim Kohler
              wrote on last edited by
              #6

              Heath, I was able to get around this by resorting to interop. I just wrapped a call to the CreateFile function and then instantiated a FileStream object using the file handle (IntPtr) returned from CreateFile. Once I took this route everything works fine. It looks like there's a bug in the FCL when the FileStream class goes to open the files. Anyway, just an FYI. thanks again Tim

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups