filestream.cs
来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 911 行 · 第 1/2 页
CS
911 行
/* * FileStream.cs - Implementation of the "System.IO.FileStream" class. * * Copyright (C) 2001, 2003 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */namespace System.IO{using System;using System.Security;using System.Threading;using Platform;public class FileStream : Stream{ // Default buffer size used for files. internal const int BUFSIZ = 4096; // Invalid handle value. private static readonly IntPtr invalidHandle = FileMethods.GetInvalidHandle(); // Internal state. private IntPtr handle; private FileAccess access; private bool ownsHandle; private bool isAsync; private String path; // Buffer information. private int bufferSize; private byte[] buffer; private int bufferPosn; private int bufferLen; private long position; private bool bufferOwnedByWrite; private bool canSeek; // Constructor. public FileStream(String path, FileMode mode) : this(path, mode, FileAccess.ReadWrite, FileShare.Read, BUFSIZ, false) { // Nothing to do here. } public FileStream(String path, FileMode mode, FileAccess access) : this(path, mode, access, FileShare.Read, BUFSIZ, false) { // Nothing to do here. } public FileStream(String path, FileMode mode, FileAccess access, FileShare share) : this(path, mode, access, share, BUFSIZ, false) { // Nothing to do here. } public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize) : this(path, mode, access, share, bufferSize, false) { // Nothing to do here. } public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) { // Validate the parameters. if(path == null) { throw new ArgumentNullException("path"); } if(!FileMethods.ValidatePathname(path)) { throw new ArgumentException(_("IO_InvalidPathname")); } if(bufferSize <= 0) { throw new ArgumentOutOfRangeException ("bufferSize", _("ArgRange_BufferSize")); } if(access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException ("access", _("IO_FileAccess")); } if(mode < FileMode.CreateNew || mode > FileMode.Append) { throw new ArgumentOutOfRangeException ("mode", _("IO_FileMode")); } #if ECMA_COMPAT if((((int)share) & ~0x03) != 0) #else if((((int)share) & ~0x13) != 0) #endif { throw new ArgumentOutOfRangeException ("share", _("IO_FileShare")); } // Attempt to open the file. if(!FileMethods.Open(path, mode, access, share, out handle)) { Errno errno = FileMethods.GetErrno(); if(errno == Errno.ENOENT) { // // Under UNIX ENOENT is returned if the // directory the file lives in doesn't exist. // ECMA requires DirectoryNotFountException // in that case. // String dirname = System.IO.Path.GetDirectoryName(path); if (!System.IO.Directory.Exists(dirname)) throw new DirectoryNotFoundException(); throw new FileNotFoundException(null, path); } else if(errno == Errno.ENOTDIR) { throw new DirectoryNotFoundException(); } else if(errno == Errno.ENAMETOOLONG) { throw new PathTooLongException(); } else if(errno == Errno.EACCES) { throw new UnauthorizedAccessException(); } else { throw new IOException(errno); } } // Initialize the object state. this.access = access; this.ownsHandle = true; this.isAsync = useAsync; this.path = path; this.bufferSize = bufferSize; this.buffer = new byte [bufferSize]; this.bufferPosn = 0; this.bufferLen = 0; this.bufferOwnedByWrite = false; this.canSeek = FileMethods.CanSeek(handle); this.position = 0; } // Non-ECMA constructors.#if !ECMA_COMPAT public FileStream(IntPtr handle, FileAccess access) : this(handle, access, true, BUFSIZ, false) { // Nothing to do here. } public FileStream(IntPtr handle, FileAccess access, bool ownsHandle) : this(handle, access, ownsHandle, BUFSIZ, false) { // Nothing to do here. } public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize) : this(handle, access, ownsHandle, bufferSize, false) { // Nothing to do here. } public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync) { // Validate the parameters. if(bufferSize <= 0) { throw new ArgumentOutOfRangeException ("bufferSize", _("ArgRange_BufferSize")); } if(access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException ("access", _("IO_FileAccess")); } #if false if(!FileMethods.CheckHandleAccess(handle, access)) { throw new UnauthorizedAccessException (_("IO_IncorrectAccess")); } #endif // Initialize the object state. this.handle = handle; this.access = access; this.ownsHandle = ownsHandle; this.isAsync = isAsync; this.bufferSize = bufferSize; this.buffer = new byte [bufferSize]; this.bufferPosn = 0; this.bufferLen = 0; this.bufferOwnedByWrite = false; this.canSeek = FileMethods.CanSeek(handle); if(canSeek) { this.position = FileMethods.Seek (handle, 0, SeekOrigin.Current); } else { this.position = 0; } } // Internal constructor used by IsolatedStorageFileStream. internal FileStream(String path) { this.path = path; }#endif // Destructor. ~FileStream() { Dispose(false); } // Asynchronous operations - let the base class do the work. public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { return base.BeginRead(buffer, offset, count, callback, state); } public override int EndRead(IAsyncResult asyncResult) { return base.EndRead(asyncResult); } public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { return base.BeginWrite(buffer, offset, count, callback, state); } public override void EndWrite(IAsyncResult asyncResult) { base.EndWrite(asyncResult); } // Flush read data from the buffer. private void FlushReadBuffer() { if(canSeek) { if(bufferPosn < bufferLen) { FileMethods.Seek(handle, -bufferPosn, SeekOrigin.Current); position -= bufferPosn; } bufferPosn = 0; bufferLen = 0; } } // Flush any buffered write data to the file. private void FlushWriteBuffer() { if(bufferPosn > 0) { if(!FileMethods.Write(handle, buffer, 0, bufferPosn)) { throw new IOException (FileMethods.GetErrno(), _("IO_WriteFailed")); } bufferPosn = 0; } } // Set up for a read. private void SetupRead() { if((access & FileAccess.Read) == 0) { throw new NotSupportedException (_("IO_NotSupp_Read")); } if(handle == invalidHandle) { throw new ObjectDisposedException(_("IO_StreamClosed")); } if(bufferOwnedByWrite) { FlushWriteBuffer(); bufferOwnedByWrite = false; } } // Set up for a write. private void SetupWrite() { if((access & FileAccess.Write) == 0) { throw new NotSupportedException(_("IO_NotSupp_Write")); } if(handle == invalidHandle) { throw new ObjectDisposedException(_("IO_StreamClosed")); } if(!bufferOwnedByWrite) { FlushReadBuffer(); bufferOwnedByWrite = true; } } // Close the stream. public override void Close() { Dispose(true); GC.SuppressFinalize(this); } // Dispose of this stream. protected virtual void Dispose(bool disposing) { lock(this) { if(handle != invalidHandle) { if(bufferOwnedByWrite) { FlushWriteBuffer(); } if(ownsHandle) { FileMethods.Close(handle); } handle = invalidHandle; } } } // Flush the pending contents in this stream. public override void Flush() { lock(this) { if(handle != invalidHandle) { if(bufferOwnedByWrite) { FlushWriteBuffer(); if(!FileMethods.FlushWrite(handle)) { throw new IOException (FileMethods.GetErrno(), _("IO_FlushFailed")); } } else { FlushReadBuffer(); } } else { throw new ObjectDisposedException (_("IO_StreamClosed")); } } } // Read data from this stream. public override int Read(byte[] buffer, int offset, int count) { int readLen = 0; int tempLen; // Validate the parameters and setup the object for reading. ValidateBuffer(buffer, offset, count); // Lock down the file stream while we do this. lock(this) { // Set up for the read operation. SetupRead(); // Read data into the caller's buffer. while(count > 0) { // How much data do we have available in the buffer? tempLen = bufferLen - bufferPosn; if(tempLen <= 0) { bufferPosn = 0; bufferLen = FileMethods.Read (handle, this.buffer, 0, bufferSize); if(bufferLen < 0) { bufferLen = 0; throw new IOException (FileMethods.GetErrno(), _("IO_ReadFailed")); } else if(bufferLen == 0) { break; } else { tempLen = bufferLen; } } // Don't read more than the caller wants. if(tempLen > count) { tempLen = count; } // Copy stream data to the caller's buffer. Array.Copy(this.buffer, bufferPosn, buffer, offset, tempLen); // Advance to the next buffer positions. readLen += tempLen; offset += tempLen; count -= tempLen; bufferPosn += tempLen; position += tempLen; } } // Return the number of bytes that were read to the caller. return readLen; } // Read a single byte from this stream.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?