2 // System.IO.StreamWriter.cs
\r
5 // Dietmar Maurer (dietmar@ximian.com)
\r
7 // (C) Ximian, Inc. http://www.ximian.com
\r
13 namespace System.IO {
\r
16 public class StreamWriter : TextWriter {
\r
18 private Encoding internalEncoding;
\r
20 private Stream internalStream;
\r
21 private bool closed = false;
\r
23 private bool iflush;
\r
25 private const int DefaultBufferSize = 1024;
\r
26 private const int DefaultFileBufferSize = 4096;
\r
27 private const int MinimumBufferSize = 2;
\r
30 private int BufferSize;
\r
31 private byte[] TheBuffer;
\r
33 private bool DisposedAlready = false;
\r
35 public new static readonly StreamWriter Null = new StreamWriter (Stream.Null, Encoding.UTF8, 0);
\r
37 public StreamWriter (Stream stream)
\r
38 : this (stream, new UTF8Encoding (false, true), DefaultBufferSize) {}
\r
40 public StreamWriter (Stream stream, Encoding encoding)
\r
41 : this (stream, encoding, DefaultBufferSize) {}
\r
43 internal void Initialize(Encoding encoding, int bufferSize) {
\r
44 internalEncoding = encoding;
\r
46 BufferSize = Math.Max(bufferSize, MinimumBufferSize);
\r
47 TheBuffer = new byte[BufferSize];
\r
50 //[MonoTODO("Nothing is done with bufferSize")]
\r
51 public StreamWriter (Stream stream, Encoding encoding, int bufferSize) {
\r
53 throw new ArgumentNullException("stream");
\r
54 if (null == encoding)
\r
55 throw new ArgumentNullException("encoding");
\r
57 throw new ArgumentOutOfRangeException("bufferSize");
\r
58 if (!stream.CanWrite)
\r
59 throw new ArgumentException("bufferSize");
\r
61 internalStream = stream;
\r
63 Initialize(encoding, bufferSize);
\r
66 public StreamWriter (string path)
\r
67 : this (path, false, Encoding.UTF8, DefaultFileBufferSize) {}
\r
69 public StreamWriter (string path, bool append)
\r
70 : this (path, append, Encoding.UTF8, DefaultFileBufferSize) {}
\r
72 public StreamWriter (string path, bool append, Encoding encoding)
\r
73 : this (path, append, encoding, DefaultFileBufferSize) {}
\r
75 public StreamWriter (string path, bool append, Encoding encoding, int bufferSize) {
\r
77 throw new ArgumentNullException("path");
\r
78 if (String.Empty == path)
\r
79 throw new ArgumentException("path cannot be empty string");
\r
80 if (path.IndexOfAny (Path.InvalidPathChars) != -1)
\r
81 throw new ArgumentException("path contains invalid characters");
\r
83 if (null == encoding)
\r
84 throw new ArgumentNullException("encoding");
\r
86 throw new ArgumentOutOfRangeException("bufferSize");
\r
88 string DirName = Path.GetDirectoryName(path);
\r
89 if (DirName != String.Empty && !Directory.Exists(DirName))
\r
90 throw new DirectoryNotFoundException();
\r
95 mode = FileMode.Append;
\r
97 mode = FileMode.Create;
\r
99 internalStream = new FileStream (path, mode, FileAccess.Write);
\r
102 internalStream.Position = internalStream.Length;
\r
104 internalStream.SetLength (0);
\r
106 Initialize(encoding, bufferSize);
\r
109 public virtual bool AutoFlush {
\r
118 public virtual Stream BaseStream {
\r
120 return internalStream;
\r
124 public override Encoding Encoding {
\r
126 return internalEncoding;
\r
130 protected override void Dispose (bool disposing) {
\r
131 if (!DisposedAlready && disposing && internalStream != null) {
\r
133 DisposedAlready = true;
\r
134 internalStream.Close ();
\r
137 internalStream = null;
\r
139 internalEncoding = null;
\r
142 public override void Flush () {
\r
143 if (DisposedAlready)
\r
144 throw new ObjectDisposedException("StreamWriter");
\r
147 internalStream.Write (TheBuffer, 0, pos);
\r
148 internalStream.Flush ();
\r
153 public override void Write (char[] buffer, int index, int count) {
\r
154 if (DisposedAlready)
\r
155 throw new ObjectDisposedException("StreamWriter");
\r
157 byte[] res = new byte [internalEncoding.GetByteCount (buffer)];
\r
162 len = internalEncoding.GetBytes (buffer, index, count, res, 0);
\r
164 // if they want AutoFlush, don't bother buffering
\r
167 internalStream.Write (res, 0, len);
\r
168 internalStream.Flush ();
\r
170 // otherwise use the buffer.
\r
171 // NOTE: this logic is not optimized for performance.
\r
172 while (resPos < len) {
\r
173 // fill the buffer if we've got more bytes than will fit
\r
174 BytesToBuffer = Math.Min(BufferSize - pos, len - resPos);
\r
175 Array.Copy(res, resPos, TheBuffer, pos, BytesToBuffer);
\r
176 resPos += BytesToBuffer;
\r
177 pos += BytesToBuffer;
\r
178 // if the buffer is full, flush it out.
\r
179 if (pos == BufferSize) Flush();
\r
184 public override void Write (char value)
\r
186 Write (new char [] {value}, 0, 1);
\r
189 public override void Write (char [] value)
\r
191 Write (value, 0, value.Length);
\r
194 public override void Write(string value) {
\r
195 if (DisposedAlready)
\r
196 throw new ObjectDisposedException("StreamWriter");
\r
199 Write (value.ToCharArray (), 0, value.Length);
\r
202 public override void Close()
\r