// Set the length of this stream. public override void SetLength(long value) { // Validate the parameters and setup the object for writing. if (value < 0) { throw new ArgumentOutOfRangeException ("value", _("ArgRange_NonNegative")); } if (!canSeek) { throw new NotSupportedException(_("IO_NotSupp_Seek")); } // Lock down the file stream while we do this. lock (this) { // Setup this object for writing. SetupWrite(); // Call the underlying platform's "SetLength" method. if (!FileMethods.SetLength(handle, value)) { throw new IOException (FileMethods.GetErrno(), _("IO_SetLengthFailed")); } } }
// Unlock a region of the file stream. public virtual void Unlock(long position, long length) { if (position < 0) { throw new ArgumentOutOfRangeException ("position", _("ArgRange_NonNegative")); } if (length < 0) { throw new ArgumentOutOfRangeException ("position", _("ArgRange_NonNegative")); } lock (this) { if (handle == invalidHandle) { throw new ObjectDisposedException(_("IO_StreamClosed")); } if (!FileMethods.Unlock(handle, position, length)) { throw new IOException (FileMethods.GetErrno(), _("IO_UnlockFailed")); } } }
// Write a single byte to this stream. public override void WriteByte(byte value) { // Lock down the file stream while we do this. lock (this) { // Setup the object for writing. SetupWrite(); // Flush the current buffer if it is full. if (bufferPosn >= bufferSize) { if (!FileMethods.Write (handle, this.buffer, 0, bufferPosn)) { throw new IOException (FileMethods.GetErrno(), _("IO_WriteFailed")); } bufferPosn = 0; } // Write the byte into the buffer and advance the posn. buffer[bufferPosn++] = value; ++position; } }
// Read a single byte from this stream. public override int ReadByte() { // Lock down the file stream while we do this. lock (this) { // Setup the object for reading. SetupRead(); // Read more data into the internal buffer if necessary. if (bufferPosn >= bufferLen) { bufferPosn = 0; bufferLen = FileMethods.Read (handle, buffer, 0, bufferSize); if (bufferLen < 0) { bufferLen = 0; throw new IOException (FileMethods.GetErrno(), _("IO_ReadFailed")); } else if (bufferLen == 0) { // We've reached EOF. return(-1); } } // Extract the next byte from the buffer. ++position; return(buffer[bufferPosn++]); } }
// 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")); } } }
// 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; } bufferLen = 0; }
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(System.IO.Path.GetFullPath(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; }
// Write a buffer of bytes to this stream. public override void Write(byte[] buffer, int offset, int count) { int tempLen; // Validate the parameters and setup the object for writing. ValidateBuffer(buffer, offset, count); // Lock down the file stream while we do this. lock (this) { // Setup this object for writing. SetupWrite(); // Write data to the file stream. while (count > 0) { // Determine how many bytes we can write to the buffer. tempLen = bufferSize - bufferPosn; if (tempLen <= 0) { // Flush the current buffer contents. if (!FileMethods.Write (handle, this.buffer, 0, bufferPosn)) { throw new IOException (FileMethods.GetErrno(), _("IO_WriteFailed")); } bufferPosn = 0; tempLen = bufferSize; } if (tempLen > count) { tempLen = count; } // Can we short-cut the internal buffer? if (bufferPosn == 0 && tempLen == bufferSize) { // Yes: write the data directly to the file. if (!FileMethods.Write (handle, buffer, offset, tempLen)) { throw new IOException (FileMethods.GetErrno(), _("IO_WriteFailed")); } } else { // No: copy the data to the write buffer first. Array.Copy(buffer, offset, this.buffer, bufferPosn, tempLen); bufferPosn += tempLen; } // Advance the buffer and stream positions. position += tempLen; offset += tempLen; count -= tempLen; } // If the buffer is full, then do a speculative flush now, // rather than waiting for the next call to this method. if (bufferPosn >= bufferSize) { if (!FileMethods.Write (handle, this.buffer, 0, bufferPosn)) { throw new IOException (FileMethods.GetErrno(), _("IO_WriteFailed")); } bufferPosn = 0; } } }
// 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); }