I'm implementing the first answer to my earlier question about redirecting the output of Print[ ]. Opening a file with OpenWrite[] and assigning the stream to $Output seems to work satisfactorily. However, Close[] gives the error message shown below, and doesn't close the file. Does anyone know what's wrong? (Print statements and other code goes between opening the output stream and attempting to close it)

enter image description here


1 Answer 1


Your problem is with not reassigning $Output back to stdout. You could do it by writing your code like so:

fname = FileNameJoin[{HomeDirectory[], "Desktop", "test.txt"}];
Module[{out = $Output},
  $Output = OpenWrite[fname, FormatType -> OutputForm];
  Write[$Output, "The quick brown fox ..."];
  $Output = out]

The file written out by this code looks like this:

The quick brown fox ...
OutputStream[/Users/oldmg/Desktop/test.txt, 126]

The file is properly closed and no error messages ensue. However, I don't think that's good practice. I much prefer this approach which makes reassignment unnecessary:

Block[{$Output = OpenWrite[fname, FormatType -> OutputForm]},
   Write[$Output, "The quick brown fox ..."];


As rcollyer points out in a comment, it is a good idea have some error handling; in particular, the file should be closed even if an abort should occur between the time the file is opened and the time it is closed.

Block[{$Output, rtn},
  rtn = OpenWrite[fname, FormatType -> OutputForm];
  If[rtn === $Failed,
      $Output = rtn;
      Write[$Output, "The quick brown fox ..."];
  • $\begingroup$ Something like this code, maybe? $\endgroup$
    – rcollyer
    Aug 13, 2013 at 1:29
  • $\begingroup$ @rcollyer. Yes, but I wasn't aware of that post. I neglected to follow the link to it given above. It looks like the OP didn't thoroughly understand the advice given there, so still needs a push in the right direction. $\endgroup$
    – m_goldberg
    Aug 13, 2013 at 2:50
  • $\begingroup$ Likely that is exactly what happened. My only issue with your code is there is no error handling. If an Abort is issued, the stream is not closed. This question has a few strategies for handling that. $\endgroup$
    – rcollyer
    Aug 13, 2013 at 3:00
  • $\begingroup$ Yes, it would be better wrap the file I/O with AbortProtect. I'll make an update that does that. $\endgroup$
    – m_goldberg
    Aug 13, 2013 at 3:07
  • $\begingroup$ To toot my own horn, I like BlockStream, but there is some evidence that Internal`WithLocalSettings handles most cases, and I tend to use it almost exclusively, now. Definitely something to keep in ones tool chest. $\endgroup$
    – rcollyer
    Aug 13, 2013 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.