using System; using System.IO.IsolatedStorage; using System.Runtime.InteropServices; using System.Runtime.Remoting.Messaging; using Microsoft.Win32.SafeHandles; namespace System.IO { /// Exposes a around a file, supporting both synchronous and asynchronous read and write operations. /// 1 // Token: 0x020001BB RID: 443 [ComVisible(true)] public class FileStream : Stream { /// Initializes a new instance of the class for the specified file handle, with the specified read/write permission. /// A file handle for the file that the current FileStream object will encapsulate. /// A constant that sets the and properties of the FileStream object. /// /// is not a field of . /// The caller does not have the required permission. /// An I/O error occurs, such as a disk error.-or-The stream has been closed. /// The requested is not permitted by the operating system for the specified file handle, such as when is Write or ReadWrite and the file handle is set for read-only access. // Token: 0x06001699 RID: 5785 RVA: 0x00056D04 File Offset: 0x00054F04 [Obsolete("Use FileStream(SafeFileHandle handle, FileAccess access) instead")] public FileStream(IntPtr handle, FileAccess access) : this(handle, access, true, 8192, false) { } /// Initializes a new instance of the class for the specified file handle, with the specified read/write permission and FileStream instance ownership. /// A file handle for the file that the current FileStream object will encapsulate. /// A constant that gets the and properties of the FileStream object. /// true if the file handle will be owned by this FileStream instance; otherwise, false. /// /// is not a field of . /// The caller does not have the required permission. /// An I/O error occurs, such as a disk error.-or-The stream has been closed. /// The requested is not permitted by the operating system for the specified file handle, such as when is Write or ReadWrite and the file handle is set for read-only access. // Token: 0x0600169A RID: 5786 RVA: 0x00056D18 File Offset: 0x00054F18 [Obsolete("Use FileStream(SafeFileHandle handle, FileAccess access) instead")] public FileStream(IntPtr handle, FileAccess access, bool ownsHandle) : this(handle, access, ownsHandle, 8192, false) { } /// Initializes a new instance of the class for the specified file handle, with the specified read/write permission, FileStream instance ownership, and buffer size. /// A file handle for the file that this FileStream object will encapsulate. /// A constant that gets the and properties of the FileStream object. /// true if the file handle will be owned by this FileStream instance; otherwise, false. /// A positive value greater than 0 indicating the buffer size. For values between one and eight, the actual buffer size is set to eight bytes. /// /// is negative. /// An I/O error occurs, such as a disk error.-or-The stream has been closed. /// The caller does not have the required permission. /// The requested is not permitted by the operating system for the specified file handle, such as when is Write or ReadWrite and the file handle is set for read-only access. // Token: 0x0600169B RID: 5787 RVA: 0x00056D2C File Offset: 0x00054F2C [Obsolete("Use FileStream(SafeFileHandle handle, FileAccess access, int bufferSize) instead")] public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize) : this(handle, access, ownsHandle, bufferSize, false) { } /// Initializes a new instance of the class for the specified file handle, with the specified read/write permission, FileStream instance ownership, buffer size, and synchronous or asynchronous state. /// A file handle for the file that this FileStream object will encapsulate. /// A constant that gets the and properties of the FileStream object. /// true if the file handle will be owned by this FileStream instance; otherwise, false. /// A positive value greater than 0 indicating the buffer size. For values between one and eight, the actual buffer size is set to eight bytes. /// true if the handle was opened asynchronously (that is, in overlapped I/O mode); otherwise, false. /// /// is less than FileAccess.Read or greater than FileAccess.ReadWrite or is less than or equal to 0. /// The handle is invalid. /// An I/O error occurs, such as a disk error.-or-The stream has been closed. /// The caller does not have the required permission. /// The requested is not permitted by the operating system for the specified file handle, such as when is Write or ReadWrite and the file handle is set for read-only access. // Token: 0x0600169C RID: 5788 RVA: 0x00056D3C File Offset: 0x00054F3C [Obsolete("Use FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync) instead")] public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync) : this(handle, access, ownsHandle, bufferSize, isAsync, false) { } // Token: 0x0600169D RID: 5789 RVA: 0x00056D4C File Offset: 0x00054F4C internal FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool noBuffering) { this.name = "[Unknown]"; base..ctor(); this.handle = MonoIO.InvalidHandle; if (handle == this.handle) { throw new ArgumentException("handle", Locale.GetText("Invalid.")); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } MonoIOError monoIOError; MonoFileType fileType = MonoIO.GetFileType(handle, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.name, monoIOError); } if (fileType == MonoFileType.Unknown) { throw new IOException("Invalid handle."); } if (fileType == MonoFileType.Disk) { this.canseek = true; } else { this.canseek = false; } this.handle = handle; this.access = access; this.owner = ownsHandle; this.async = isAsync; this.anonymous = false; this.InitBuffer(bufferSize, noBuffering); if (this.canseek) { this.buf_start = MonoIO.Seek(handle, 0L, SeekOrigin.Current, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.name, monoIOError); } } this.append_startpos = 0L; } /// Initializes a new instance of the class with the specified path and creation mode. /// A relative or absolute path for the file that the current FileStream object will encapsulate. /// A constant that determines how to open or create the file. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. -or- refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment. /// /// refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment. /// /// is null. /// The caller does not have the required permission. /// The file cannot be found, such as when is FileMode.Truncate or FileMode.Open, and the file specified by does not exist. The file must already exist in these modes. /// An I/O error occurs, such as specifying FileMode.CreateNew and the file specified by already exists.-or-The stream has been closed. /// The specified path is invalid, such as being on an unmapped drive. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. /// /// contains an invalid value. // Token: 0x0600169E RID: 5790 RVA: 0x00056E60 File Offset: 0x00055060 public FileStream(string path, FileMode mode) : this(path, mode, (mode != FileMode.Append) ? FileAccess.ReadWrite : FileAccess.Write, FileShare.Read, 8192, false, FileOptions.None) { } /// Initializes a new instance of the class with the specified path, creation mode, and read/write permission. /// A relative or absolute path for the file that the current FileStream object will encapsulate. /// A constant that determines how to open or create the file. /// A constant that determines how the file can be accessed by the FileStream object. This gets the and properties of the FileStream object. is true if specifies a disk file. /// /// is null. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. -or- refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment. /// /// refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. /// The file cannot be found, such as when is FileMode.Truncate or FileMode.Open, and the file specified by does not exist. The file must already exist in these modes. /// An I/O error occurs, such as specifying FileMode.CreateNew and the file specified by already exists. -or-The stream has been closed. /// The caller does not have the required permission. /// The specified path is invalid, such as being on an unmapped drive. /// The requested is not permitted by the operating system for the specified , such as when is Write or ReadWrite and the file or directory is set for read-only access. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. /// /// contains an invalid value. // Token: 0x0600169F RID: 5791 RVA: 0x00056E8C File Offset: 0x0005508C public FileStream(string path, FileMode mode, FileAccess access) : this(path, mode, access, (access != FileAccess.Write) ? FileShare.Read : FileShare.None, 8192, false, false) { } /// Initializes a new instance of the class with the specified path, creation mode, read/write permission, and sharing permission. /// A relative or absolute path for the file that the current FileStream object will encapsulate. /// A constant that determines how to open or create the file. /// A constant that determines how the file can be accessed by the FileStream object. This gets the and properties of the FileStream object. is true if specifies a disk file. /// A constant that determines how the file will be shared by processes. /// /// is null. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. -or- refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment. /// /// refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. /// The file cannot be found, such as when is FileMode.Truncate or FileMode.Open, and the file specified by does not exist. The file must already exist in these modes. /// An I/O error occurs, such as specifying FileMode.CreateNew and the file specified by already exists. -or-The system is running Windows 98 or Windows 98 Second Edition and is set to FileShare.Delete.-or-The stream has been closed. /// The caller does not have the required permission. /// The specified path is invalid, such as being on an unmapped drive. /// The requested is not permitted by the operating system for the specified , such as when is Write or ReadWrite and the file or directory is set for read-only access. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. /// /// contains an invalid value. // Token: 0x060016A0 RID: 5792 RVA: 0x00056EB8 File Offset: 0x000550B8 public FileStream(string path, FileMode mode, FileAccess access, FileShare share) : this(path, mode, access, share, 8192, false, FileOptions.None) { } /// Initializes a new instance of the class with the specified path, creation mode, read/write and sharing permission, and buffer size. /// A relative or absolute path for the file that the current FileStream object will encapsulate. /// A constant that determines how to open or create the file. /// A constant that determines how the file can be accessed by the FileStream object. This gets the and properties of the FileStream object. is true if specifies a disk file. /// A constant that determines how the file will be shared by processes. /// A positive value greater than 0 indicating the buffer size. For values between one and eight, the actual buffer size is set to eight bytes. /// /// is null. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. -or- refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment. /// /// refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. /// /// is negative or zero.-or- , , or contain an invalid value. /// The file cannot be found, such as when is FileMode.Truncate or FileMode.Open, and the file specified by does not exist. The file must already exist in these modes. /// An I/O error occurs, such as specifying FileMode.CreateNew and the file specified by already exists. -or-The system is running Windows 98 or Windows 98 Second Edition and is set to FileShare.Delete.-or-The stream has been closed. /// The caller does not have the required permission. /// The specified path is invalid, such as being on an unmapped drive. /// The requested is not permitted by the operating system for the specified , such as when is Write or ReadWrite and the file or directory is set for read-only access. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. // Token: 0x060016A1 RID: 5793 RVA: 0x00056ED8 File Offset: 0x000550D8 public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize) : this(path, mode, access, share, bufferSize, false, FileOptions.None) { } /// Initializes a new instance of the class with the specified path, creation mode, read/write and sharing permission, buffer size, and synchronous or asynchronous state. /// A relative or absolute path for the file that the current FileStream object will encapsulate. /// A constant that determines how to open or create the file. /// A constant that determines how the file can be accessed by the FileStream object. This gets the and properties of the FileStream object. is true if specifies a disk file. /// A constant that determines how the file will be shared by processes. /// A positive value greater than 0 indicating the buffer size. For values between one and eight, the actual buffer size is set to eight bytes. /// Specifies whether to use asynchronous I/O or synchronous I/O. However, note that the underlying operating system might not support asynchronous I/O, so when specifying true, the handle might be opened synchronously depending on the platform. When opened asynchronously, the and methods perform better on large reads or writes, but they might be much slower for small reads or writes. If the application is designed to take advantage of asynchronous I/O, set the parameter to true. Using asynchronous I/O correctly can speed up applications by as much as a factor of 10, but using it without redesigning the application for asynchronous I/O can decrease performance by as much as a factor of 10. /// /// is null. /// /// is an empty string (""), contains only white space, or contains one or more invalid characters. -or- refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment. /// /// refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment. /// /// is negative or zero.-or- , , or contain an invalid value. /// The file cannot be found, such as when is FileMode.Truncate or FileMode.Open, and the file specified by does not exist. The file must already exist in these modes. /// An I/O error occurs, such as specifying FileMode.CreateNew and the file specified by already exists.-or- The system is running Windows 98 or Windows 98 Second Edition and is set to FileShare.Delete.-or-The stream has been closed. /// The caller does not have the required permission. /// The specified path is invalid, such as being on an unmapped drive. /// The requested is not permitted by the operating system for the specified , such as when is Write or ReadWrite and the file or directory is set for read-only access. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. // Token: 0x060016A2 RID: 5794 RVA: 0x00056EF4 File Offset: 0x000550F4 public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) : this(path, mode, access, share, bufferSize, useAsync, FileOptions.None) { } // Token: 0x060016A3 RID: 5795 RVA: 0x00056F14 File Offset: 0x00055114 internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool isAsync, bool anonymous) : this(path, mode, access, share, bufferSize, anonymous, (!isAsync) ? FileOptions.None : FileOptions.Asynchronous) { } // Token: 0x060016A4 RID: 5796 RVA: 0x00056F44 File Offset: 0x00055144 internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool anonymous, FileOptions options) { this.name = "[Unknown]"; base..ctor(); if (path == null) { throw new ArgumentNullException("path"); } if (path.Length == 0) { throw new ArgumentException("Path is empty"); } share &= ~FileShare.Inheritable; if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", "Positive number required."); } if (mode < FileMode.CreateNew || mode > FileMode.Append) { if (anonymous) { throw new ArgumentException("mode", "Enum value was out of legal range."); } throw new ArgumentOutOfRangeException("mode", "Enum value was out of legal range."); } else if (access < FileAccess.Read || access > FileAccess.ReadWrite) { if (anonymous) { throw new IsolatedStorageException("Enum value for FileAccess was out of legal range."); } throw new ArgumentOutOfRangeException("access", "Enum value was out of legal range."); } else if ((share < FileShare.None) || share > (FileShare.Read | FileShare.Write | FileShare.Delete)) { if (anonymous) { throw new IsolatedStorageException("Enum value for FileShare was out of legal range."); } throw new ArgumentOutOfRangeException("share", "Enum value was out of legal range."); } else { if (path.IndexOfAny(Path.InvalidPathChars) != -1) { throw new ArgumentException("Name has invalid chars"); } if (Directory.Exists(path)) { string text = Locale.GetText("Access to the path '{0}' is denied."); throw new UnauthorizedAccessException(string.Format(text, this.GetSecureFileName(path, false))); } if (mode == FileMode.Append && (access & FileAccess.Read) == FileAccess.Read) { throw new ArgumentException("Append access can be requested only in write-only mode."); } if ((access & FileAccess.Write) == (FileAccess)0 && mode != FileMode.Open && mode != FileMode.OpenOrCreate) { string text2 = Locale.GetText("Combining FileMode: {0} with FileAccess: {1} is invalid."); throw new ArgumentException(string.Format(text2, access, mode)); } string text3; if (Path.DirectorySeparatorChar != '/' && path.IndexOf('/') >= 0) { text3 = Path.GetDirectoryName(Path.GetFullPath(path)); } else { text3 = Path.GetDirectoryName(path); } if (text3.Length > 0) { string fullPath = Path.GetFullPath(text3); if (!Directory.Exists(fullPath)) { string text4 = Locale.GetText("Could not find a part of the path \"{0}\"."); string text5 = ((!anonymous) ? Path.GetFullPath(path) : text3); throw new IsolatedStorageException(string.Format(text4, text5)); } } if (access == FileAccess.Read && mode != FileMode.Create && mode != FileMode.OpenOrCreate && mode != FileMode.CreateNew && !File.Exists(path)) { string text6 = Locale.GetText("Could not find file \"{0}\"."); string secureFileName = this.GetSecureFileName(path); throw new IsolatedStorageException(string.Format(text6, secureFileName)); } if (!anonymous) { this.name = path; } MonoIOError monoIOError; this.handle = MonoIO.Open(path, mode, access, share, options, out monoIOError); if (this.handle == MonoIO.InvalidHandle) { throw MonoIO.GetException(this.GetSecureFileName(path), monoIOError); } this.access = access; this.owner = true; this.anonymous = anonymous; if (MonoIO.GetFileType(this.handle, out monoIOError) == MonoFileType.Disk) { this.canseek = true; this.async = (options & FileOptions.Asynchronous) != FileOptions.None; } else { this.canseek = false; this.async = false; } if (access == FileAccess.Read && this.canseek && bufferSize == 8192) { long length = this.Length; if ((long)bufferSize > length) { bufferSize = (int)((length >= 1000L) ? length : 1000L); } } this.InitBuffer(bufferSize, false); if (mode == FileMode.Append) { this.Seek(0L, SeekOrigin.End); this.append_startpos = this.Position; } else { this.append_startpos = 0L; } return; } } /// Gets a value indicating whether the current stream supports reading. /// true if the stream supports reading; false if the stream is closed or was opened with write-only access. /// 1 // Token: 0x170003F8 RID: 1016 // (get) Token: 0x060016A5 RID: 5797 RVA: 0x000572C4 File Offset: 0x000554C4 public override bool CanRead { get { return this.access == FileAccess.Read || this.access == FileAccess.ReadWrite; } } /// Gets a value indicating whether the current stream supports writing. /// true if the stream supports writing; false if the stream is closed or was opened with read-only access. /// 1 // Token: 0x170003F9 RID: 1017 // (get) Token: 0x060016A6 RID: 5798 RVA: 0x000572E0 File Offset: 0x000554E0 public override bool CanWrite { get { return this.access == FileAccess.Write || this.access == FileAccess.ReadWrite; } } /// Gets a value indicating whether the current stream supports seeking. /// true if the stream supports seeking; false if the stream is closed or if the FileStream was constructed from an operating-system handle such as a pipe or output to the console. /// 2 // Token: 0x170003FA RID: 1018 // (get) Token: 0x060016A7 RID: 5799 RVA: 0x000572FC File Offset: 0x000554FC public override bool CanSeek { get { return this.canseek; } } /// Gets a value indicating whether the FileStream was opened asynchronously or synchronously. /// true if the FileStream was opened asynchronously; otherwise, false. /// 2 // Token: 0x170003FB RID: 1019 // (get) Token: 0x060016A8 RID: 5800 RVA: 0x00057304 File Offset: 0x00055504 public virtual bool IsAsync { get { return this.async; } } /// Gets the name of the FileStream that was passed to the constructor. /// A string that is the name of the FileStream. /// 1 /// /// /// // Token: 0x170003FC RID: 1020 // (get) Token: 0x060016A9 RID: 5801 RVA: 0x0005730C File Offset: 0x0005550C public string Name { get { return this.name; } } /// Gets the length in bytes of the stream. /// A long value representing the length of the stream in bytes. /// /// for this stream is false. /// An I/O error occurs, such as the file being closed. /// 1 // Token: 0x170003FD RID: 1021 // (get) Token: 0x060016AA RID: 5802 RVA: 0x00057314 File Offset: 0x00055514 public override long Length { get { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanSeek) { throw new NotSupportedException("The stream does not support seeking"); } this.FlushBufferIfDirty(); MonoIOError monoIOError; long length = MonoIO.GetLength(this.handle, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } return length; } } /// Gets or sets the current position of this stream. /// The current position of this stream. /// The stream does not support seeking. /// An I/O error occurs. - or -The position was set to a very large value beyond the end of the stream in Windows 98 or earlier. /// Attempted to set the position to a negative value. /// Attempted seeking past the end of a stream that does not support this. /// 1 // Token: 0x170003FE RID: 1022 // (get) Token: 0x060016AB RID: 5803 RVA: 0x00057388 File Offset: 0x00055588 // (set) Token: 0x060016AC RID: 5804 RVA: 0x000573DC File Offset: 0x000555DC public override long Position { get { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanSeek) { throw new NotSupportedException("The stream does not support seeking"); } return this.buf_start + (long)this.buf_offset; } set { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanSeek) { throw new NotSupportedException("The stream does not support seeking"); } if (value < 0L) { throw new ArgumentOutOfRangeException("Attempt to set the position to a negative value"); } this.Seek(value, SeekOrigin.Begin); } } /// Gets the operating system file handle for the file that the current FileStream object encapsulates. /// The operating system file handle for the file encapsulated by this FileStream object, or -1 if the FileStream has been closed. /// The caller does not have the required permission. /// 2 /// /// /// // Token: 0x170003FF RID: 1023 // (get) Token: 0x060016AD RID: 5805 RVA: 0x0005743C File Offset: 0x0005563C [Obsolete("Use SafeFileHandle instead")] public virtual IntPtr Handle { get { return this.handle; } } /// Gets a object that represents the operating system file handle for the file that the current object encapsulates. /// A object that represents the operating system file handle for the file that the current object encapsulates. /// 1 // Token: 0x17000400 RID: 1024 // (get) Token: 0x060016AE RID: 5806 RVA: 0x00057444 File Offset: 0x00055644 public virtual SafeFileHandle SafeFileHandle { get { SafeFileHandle safeFileHandle; if (this.safeHandle != null) { safeFileHandle = this.safeHandle; } else { safeFileHandle = new SafeFileHandle(this.handle, this.owner); } this.FlushBuffer(); return safeFileHandle; } } /// Reads a byte from the file and advances the read position one byte. /// The byte, cast to an , or -1 if the end of the stream has been reached. /// The current stream does not support reading. /// The current stream is closed. /// 1 // Token: 0x060016AF RID: 5807 RVA: 0x00057484 File Offset: 0x00055684 public override int ReadByte() { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanRead) { throw new NotSupportedException("Stream does not support reading"); } if (this.buf_size != 0) { if (this.buf_offset >= this.buf_length) { this.RefillBuffer(); if (this.buf_length == 0) { return -1; } } return (int)this.buf[this.buf_offset++]; } if (this.ReadData(this.handle, this.buf, 0, 1) == 0) { return -1; } return (int)this.buf[0]; } /// Writes a byte to the current position in the file stream. /// A byte to write to the stream. /// The stream is closed. /// The stream does not support writing. /// 1 // Token: 0x060016B0 RID: 5808 RVA: 0x00057534 File Offset: 0x00055734 public override void WriteByte(byte value) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanWrite) { throw new NotSupportedException("Stream does not support writing"); } if (this.buf_offset == this.buf_size) { this.FlushBuffer(); } if (this.buf_size == 0) { this.buf[0] = value; this.buf_dirty = true; this.buf_length = 1; this.FlushBuffer(); return; } this.buf[this.buf_offset++] = value; if (this.buf_offset > this.buf_length) { this.buf_length = this.buf_offset; } this.buf_dirty = true; } /// Reads a block of bytes from the stream and writes the data in a given buffer. /// The total number of bytes read into the buffer. This might be less than the number of bytes requested if that number of bytes are not currently available, or zero if the end of the stream is reached. /// When this method returns, contains the specified byte array with the values between and ( + - replaced by the bytes read from the current source. /// The byte offset in at which the read bytes will be placed. /// The maximum number of bytes to read. /// /// is null. /// /// or is negative. /// The stream does not support reading. /// An I/O error occurs. /// /// and describe an invalid range in . /// Methods were called after the stream was closed. /// 1 // Token: 0x060016B1 RID: 5809 RVA: 0x000575F4 File Offset: 0x000557F4 public override int Read([In] [Out] byte[] array, int offset, int count) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (array == null) { throw new ArgumentNullException("array"); } if (!this.CanRead) { throw new NotSupportedException("Stream does not support reading"); } int num = array.Length; if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "< 0"); } if (count < 0) { throw new ArgumentOutOfRangeException("count", "< 0"); } if (offset > num) { throw new ArgumentException("destination offset is beyond array size"); } if (offset > num - count) { throw new ArgumentException("Reading would overrun buffer"); } if (this.async) { IAsyncResult asyncResult = this.BeginRead(array, offset, count, null, null); return this.EndRead(asyncResult); } return this.ReadInternal(array, offset, count); } // Token: 0x060016B2 RID: 5810 RVA: 0x000576C8 File Offset: 0x000558C8 private int ReadInternal(byte[] dest, int offset, int count) { int num = 0; int num2 = this.ReadSegment(dest, offset, count); num += num2; count -= num2; if (count == 0) { return num; } if (count > this.buf_size) { this.FlushBuffer(); num2 = this.ReadData(this.handle, dest, offset + num, count); this.buf_start += (long)num2; } else { this.RefillBuffer(); num2 = this.ReadSegment(dest, offset + num, count); } return num + num2; } /// Begins an asynchronous read. /// An object that references the asynchronous read. /// The buffer to read data into. /// The byte offset in at which to begin reading. /// The maximum number of bytes to read. /// The method to be called when the asynchronous read operation is completed. /// A user-provided object that distinguishes this particular asynchronous read request from other requests. /// The array length minus is less than . /// /// is null. /// /// or is negative. /// An asynchronous read was attempted past the end of the file. /// 2 // Token: 0x060016B3 RID: 5811 RVA: 0x00057744 File Offset: 0x00055944 public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanRead) { throw new NotSupportedException("This stream does not support reading"); } if (array == null) { throw new ArgumentNullException("array"); } if (numBytes < 0) { throw new ArgumentOutOfRangeException("numBytes", "Must be >= 0"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Must be >= 0"); } if (numBytes > array.Length - offset) { throw new ArgumentException("Buffer too small. numBytes/offset wrong."); } if (!this.async) { return base.BeginRead(array, offset, numBytes, userCallback, stateObject); } FileStream.ReadDelegate readDelegate = new FileStream.ReadDelegate(this.ReadInternal); return readDelegate.BeginInvoke(array, offset, numBytes, userCallback, stateObject); } /// Waits for the pending asynchronous read to complete. /// The number of bytes read from the stream, between 0 and the number of bytes you requested. Streams only return 0 at the end of the stream, otherwise, they should block until at least 1 byte is available. /// The reference to the pending asynchronous request to wait for. /// /// is null. /// This object was not created by calling on this class. /// /// is called multiple times. /// The stream is closed or an internal error has occurred. /// 2 // Token: 0x060016B4 RID: 5812 RVA: 0x00057810 File Offset: 0x00055A10 public override int EndRead(IAsyncResult asyncResult) { if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } if (!this.async) { return base.EndRead(asyncResult); } AsyncResult asyncResult2 = asyncResult as AsyncResult; if (asyncResult2 == null) { throw new ArgumentException("Invalid IAsyncResult", "asyncResult"); } FileStream.ReadDelegate readDelegate = asyncResult2.AsyncDelegate as FileStream.ReadDelegate; if (readDelegate == null) { throw new ArgumentException("Invalid IAsyncResult", "asyncResult"); } return readDelegate.EndInvoke(asyncResult); } /// Writes a block of bytes to this stream using data from a buffer. /// The buffer containing data to write to the stream. /// The zero-based byte offset in at which to begin copying bytes to the current stream. /// The number of bytes to be written to the current stream. /// /// is null. /// /// and describe an invalid range in . /// /// or is negative. /// An I/O error occurs. - or -Another thread may have caused an unexpected change in the position of the operating system's file handle. /// The stream is closed. /// The current stream instance does not support writing. /// 1 // Token: 0x060016B5 RID: 5813 RVA: 0x00057888 File Offset: 0x00055A88 public override void Write(byte[] array, int offset, int count) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (array == null) { throw new ArgumentNullException("array"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "< 0"); } if (count < 0) { throw new ArgumentOutOfRangeException("count", "< 0"); } if (offset > array.Length - count) { throw new ArgumentException("Reading would overrun buffer"); } if (!this.CanWrite) { throw new NotSupportedException("Stream does not support writing"); } if (this.async) { IAsyncResult asyncResult = this.BeginWrite(array, offset, count, null, null); this.EndWrite(asyncResult); return; } this.WriteInternal(array, offset, count); } // Token: 0x060016B6 RID: 5814 RVA: 0x00057948 File Offset: 0x00055B48 private void WriteInternal(byte[] src, int offset, int count) { if (count > this.buf_size) { this.FlushBuffer(); int i = count; while (i > 0) { MonoIOError monoIOError; int num = MonoIO.Write(this.handle, src, offset, i, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } i -= num; offset += num; } this.buf_start += (long)count; } else { int num2 = 0; while (count > 0) { int num3 = this.WriteSegment(src, offset + num2, count); num2 += num3; count -= num3; if (count == 0) { break; } this.FlushBuffer(); } } } /// Begins an asynchronous write. /// An object that references the asynchronous write. /// The buffer containing data to write to the current stream. /// The zero-based byte offset in at which to begin copying bytes to the current stream. /// The maximum number of bytes to write. /// The method to be called when the asynchronous write operation is completed. /// A user-provided object that distinguishes this particular asynchronous write request from other requests. /// /// length minus is less than . /// /// is null. /// /// or is negative. /// The stream does not support writing. /// The stream is closed. /// An I/O error occurs. /// 2 // Token: 0x060016B7 RID: 5815 RVA: 0x000579F4 File Offset: 0x00055BF4 public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanWrite) { throw new NotSupportedException("This stream does not support writing"); } if (array == null) { throw new ArgumentNullException("array"); } if (numBytes < 0) { throw new ArgumentOutOfRangeException("numBytes", "Must be >= 0"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Must be >= 0"); } if (numBytes > array.Length - offset) { throw new ArgumentException("array too small. numBytes/offset wrong."); } if (!this.async) { return base.BeginWrite(array, offset, numBytes, userCallback, stateObject); } FileStreamAsyncResult fileStreamAsyncResult = new FileStreamAsyncResult(userCallback, stateObject); fileStreamAsyncResult.BytesRead = -1; fileStreamAsyncResult.Count = numBytes; fileStreamAsyncResult.OriginalCount = numBytes; if (this.buf_dirty) { MemoryStream memoryStream = new MemoryStream(); this.FlushBuffer(memoryStream); memoryStream.Write(array, offset, numBytes); offset = 0; numBytes = (int)memoryStream.Length; } FileStream.WriteDelegate writeDelegate = new FileStream.WriteDelegate(this.WriteInternal); return writeDelegate.BeginInvoke(array, offset, numBytes, userCallback, stateObject); } /// Ends an asynchronous write, blocking until the I/O operation has completed. /// The pending asynchronous I/O request. /// /// is null. /// This object was not created by calling on this class. /// /// is called multiple times. /// The stream is closed or an internal error has occurred. /// 2 // Token: 0x060016B8 RID: 5816 RVA: 0x00057B0C File Offset: 0x00055D0C public override void EndWrite(IAsyncResult asyncResult) { if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } if (!this.async) { base.EndWrite(asyncResult); return; } AsyncResult asyncResult2 = asyncResult as AsyncResult; if (asyncResult2 == null) { throw new ArgumentException("Invalid IAsyncResult", "asyncResult"); } FileStream.WriteDelegate writeDelegate = asyncResult2.AsyncDelegate as FileStream.WriteDelegate; if (writeDelegate == null) { throw new ArgumentException("Invalid IAsyncResult", "asyncResult"); } writeDelegate.EndInvoke(asyncResult); } /// Sets the current position of this stream to the given value. /// The new position in the stream. /// The point relative to from which to begin seeking. /// Specifies the beginning, the end, or the current position as a reference point for , using a value of type . /// An I/O error occurs. /// The stream does not support seeking, such as if the FileStream is constructed from a pipe or console output. /// Attempted seeking before the beginning of the stream. /// Methods were called after the stream was closed. /// 1 // Token: 0x060016B9 RID: 5817 RVA: 0x00057B84 File Offset: 0x00055D84 public override long Seek(long offset, SeekOrigin origin) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanSeek) { throw new NotSupportedException("The stream does not support seeking"); } long num; switch (origin) { case SeekOrigin.Begin: num = offset; break; case SeekOrigin.Current: num = this.Position + offset; break; case SeekOrigin.End: num = this.Length + offset; break; default: throw new ArgumentException("origin", "Invalid SeekOrigin"); } if (num < 0L) { throw new IOException("Attempted to Seek before the beginning of the stream"); } if (num < this.append_startpos) { throw new IOException("Can't seek back over pre-existing data in append mode"); } this.FlushBuffer(); MonoIOError monoIOError; this.buf_start = MonoIO.Seek(this.handle, num, SeekOrigin.Begin, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } return this.buf_start; } /// Sets the length of this stream to the given value. /// The new length of the stream. /// An I/O error has occurred. /// The stream does not support both writing and seeking. /// Attempted to set the parameter to less than 0. /// 2 // Token: 0x060016BA RID: 5818 RVA: 0x00057C78 File Offset: 0x00055E78 public override void SetLength(long value) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (!this.CanSeek) { throw new NotSupportedException("The stream does not support seeking"); } if (!this.CanWrite) { throw new NotSupportedException("The stream does not support writing"); } if (value < 0L) { throw new ArgumentOutOfRangeException("value is less than 0"); } this.Flush(); MonoIOError monoIOError; MonoIO.SetLength(this.handle, value, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } if (this.Position > value) { this.Position = value; } } /// Clears all buffers for this stream and causes any buffered data to be written to the file system. /// An I/O error occurs. /// The stream is closed. /// 1 // Token: 0x060016BB RID: 5819 RVA: 0x00057D28 File Offset: 0x00055F28 public override void Flush() { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } this.FlushBuffer(); } /// Prevents other processes from changing the . /// The beginning of the range to lock. The value of this parameter must be equal to or greater than zero (0). /// The range to be locked. /// /// or is negative. /// The file is closed. /// The process cannot access the file because another process has locked a portion of the file. /// 2 // Token: 0x060016BC RID: 5820 RVA: 0x00057D5C File Offset: 0x00055F5C public virtual void Lock(long position, long length) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (position < 0L) { throw new ArgumentOutOfRangeException("position must not be negative"); } if (length < 0L) { throw new ArgumentOutOfRangeException("length must not be negative"); } if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } MonoIOError monoIOError; MonoIO.Lock(this.handle, position, length, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } } /// Allows access by other processes to all or part of a file that was previously locked. /// The beginning of the range to unlock. /// The range to be unlocked. /// /// or is negative. /// 2 // Token: 0x060016BD RID: 5821 RVA: 0x00057DF8 File Offset: 0x00055FF8 public virtual void Unlock(long position, long length) { if (this.handle == MonoIO.InvalidHandle) { throw new ObjectDisposedException("Stream has been closed"); } if (position < 0L) { throw new ArgumentOutOfRangeException("position must not be negative"); } if (length < 0L) { throw new ArgumentOutOfRangeException("length must not be negative"); } MonoIOError monoIOError; MonoIO.Unlock(this.handle, position, length, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } } /// Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the FileStream. // Token: 0x060016BE RID: 5822 RVA: 0x00057E74 File Offset: 0x00056074 ~FileStream() { this.Dispose(false); } /// Releases the unmanaged resources used by the and optionally releases the managed resources. /// true to release both managed and unmanaged resources; false to release only unmanaged resources. // Token: 0x060016BF RID: 5823 RVA: 0x00057EB0 File Offset: 0x000560B0 protected override void Dispose(bool disposing) { Exception ex = null; if (this.handle != MonoIO.InvalidHandle) { try { this.FlushBuffer(); } catch (Exception ex2) { ex = ex2; } if (this.owner) { MonoIOError monoIOError; MonoIO.Close(this.handle, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } this.handle = MonoIO.InvalidHandle; } } this.canseek = false; this.access = (FileAccess)0; if (disposing) { this.buf = null; } if (disposing) { GC.SuppressFinalize(this); } if (ex != null) { throw ex; } } // Token: 0x060016C0 RID: 5824 RVA: 0x00057F70 File Offset: 0x00056170 private int ReadSegment(byte[] dest, int dest_offset, int count) { if (count > this.buf_length - this.buf_offset) { count = this.buf_length - this.buf_offset; } if (count > 0) { Buffer.BlockCopy(this.buf, this.buf_offset, dest, dest_offset, count); this.buf_offset += count; } return count; } // Token: 0x060016C1 RID: 5825 RVA: 0x00057FCC File Offset: 0x000561CC private int WriteSegment(byte[] src, int src_offset, int count) { if (count > this.buf_size - this.buf_offset) { count = this.buf_size - this.buf_offset; } if (count > 0) { Buffer.BlockCopy(src, src_offset, this.buf, this.buf_offset, count); this.buf_offset += count; if (this.buf_offset > this.buf_length) { this.buf_length = this.buf_offset; } this.buf_dirty = true; } return count; } // Token: 0x060016C2 RID: 5826 RVA: 0x0005804C File Offset: 0x0005624C private void FlushBuffer(Stream st) { if (this.buf_dirty) { if (this.CanSeek) { MonoIOError monoIOError; MonoIO.Seek(this.handle, this.buf_start, SeekOrigin.Begin, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } } if (st == null) { MonoIOError monoIOError; MonoIO.Write(this.handle, this.buf, 0, this.buf_length, out monoIOError); if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } } else { st.Write(this.buf, 0, this.buf_length); } } this.buf_start += (long)this.buf_offset; this.buf_offset = (this.buf_length = 0); this.buf_dirty = false; } // Token: 0x060016C3 RID: 5827 RVA: 0x0005811C File Offset: 0x0005631C private void FlushBuffer() { this.FlushBuffer(null); } // Token: 0x060016C4 RID: 5828 RVA: 0x00058128 File Offset: 0x00056328 private void FlushBufferIfDirty() { if (this.buf_dirty) { this.FlushBuffer(null); } } // Token: 0x060016C5 RID: 5829 RVA: 0x0005813C File Offset: 0x0005633C private void RefillBuffer() { this.FlushBuffer(null); this.buf_length = this.ReadData(this.handle, this.buf, 0, this.buf_size); } // Token: 0x060016C6 RID: 5830 RVA: 0x00058170 File Offset: 0x00056370 private int ReadData(IntPtr handle, byte[] buf, int offset, int count) { MonoIOError monoIOError; int num = MonoIO.Read(handle, buf, offset, count, out monoIOError); if (monoIOError == MonoIOError.ERROR_BROKEN_PIPE) { num = 0; } else if (monoIOError != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(this.GetSecureFileName(this.name), monoIOError); } if (num == -1) { throw new IOException(); } return num; } // Token: 0x060016C7 RID: 5831 RVA: 0x000581C4 File Offset: 0x000563C4 private void InitBuffer(int size, bool noBuffering) { if (noBuffering) { size = 0; this.buf = new byte[1]; } else { if (size <= 0) { throw new ArgumentOutOfRangeException("bufferSize", "Positive number required."); } if (size < 8) { size = 8; } this.buf = new byte[size]; } this.buf_size = size; this.buf_start = 0L; this.buf_offset = (this.buf_length = 0); this.buf_dirty = false; } // Token: 0x060016C8 RID: 5832 RVA: 0x00058240 File Offset: 0x00056440 private string GetSecureFileName(string filename) { return (!this.anonymous) ? Path.GetFullPath(filename) : Path.GetFileName(filename); } // Token: 0x060016C9 RID: 5833 RVA: 0x00058260 File Offset: 0x00056460 private string GetSecureFileName(string filename, bool full) { return (!this.anonymous) ? ((!full) ? filename : Path.GetFullPath(filename)) : Path.GetFileName(filename); } // Token: 0x0400068C RID: 1676 internal const int DefaultBufferSize = 8192; // Token: 0x0400068D RID: 1677 private FileAccess access; // Token: 0x0400068E RID: 1678 private bool owner; // Token: 0x0400068F RID: 1679 private bool async; // Token: 0x04000690 RID: 1680 private bool canseek; // Token: 0x04000691 RID: 1681 private long append_startpos; // Token: 0x04000692 RID: 1682 private bool anonymous; // Token: 0x04000693 RID: 1683 private byte[] buf; // Token: 0x04000694 RID: 1684 private int buf_size; // Token: 0x04000695 RID: 1685 private int buf_length; // Token: 0x04000696 RID: 1686 private int buf_offset; // Token: 0x04000697 RID: 1687 private bool buf_dirty; // Token: 0x04000698 RID: 1688 private long buf_start; // Token: 0x04000699 RID: 1689 private string name; // Token: 0x0400069A RID: 1690 private IntPtr handle; // Token: 0x0400069B RID: 1691 private SafeFileHandle safeHandle; // Token: 0x020006C7 RID: 1735 // (Invoke) Token: 0x060041A4 RID: 16804 private delegate int ReadDelegate(byte[] buffer, int offset, int count); // Token: 0x020006C8 RID: 1736 // (Invoke) Token: 0x060041A8 RID: 16808 private delegate void WriteDelegate(byte[] buffer, int offset, int count); } }