Пример #1
0
        public Boolean WriteChunk(Byte[] buffer, Int32 length, out Int32 written)
        {
            written = 0;

            if (!this.IsValid)
            {
                throw new ArgumentException("Cannot write into file with an invalid handle value.");
            }

            if (buffer == null || buffer.Length < 1)
            {
                throw new ArgumentException("The input buffer must have a minimum length of one byte.");
            }

            if (length > buffer.Length)
            {
                throw new ArgumentException("Parameter \"length\" must be less than or equal to the length of provided buffer.");
            }

            if (!AccessHandler.WriteFile(this.handle, buffer, (UInt32)length, out UInt32 bytes, IntPtr.Zero))
            {
                throw new NativeException($"Writing into file \"{this.filename}\" has failed.", Marshal.GetHRForLastWin32Error());
            }

            written = Convert.ToInt32(bytes);

            return(written > 0 && length == written);
        }
Пример #2
0
        public Boolean ReadChunk(Byte[] buffer, out Int32 count)
        {
            count = 0;

            if (!this.IsValid)
            {
                throw new ArgumentException("Cannot read from file with an invalid handle value.");
            }

            if (buffer == null || buffer.Length < 1)
            {
                throw new ArgumentException("The result buffer must have a minimum length of one byte.");
            }

            if (!AccessHandler.ReadFile(this.handle, buffer, (UInt32)buffer.Length, out UInt32 bytes, IntPtr.Zero))
            {
                throw new NativeException($"Reading from file \"{this.filename}\" has failed.", Marshal.GetHRForLastWin32Error());
            }

            // Test for end of the file.
            if (bytes == 0)
            {
                return(false);
            }

            count = Convert.ToInt32(bytes);

            return(true);
        }
Пример #3
0
        /// <summary>
        /// Tries to create the file for provided name.
        /// </summary>
        /// <remarks>
        /// This method tries to create the file for provided name. The file creation
        /// takes place according to additional parameters. A possibly existing file
        /// will be overwritten if parameter <paramref name="overwrite"/> is <c>true</c>.
        /// The length of the new file is adjusted if parameter <paramref name="length"/>
        /// is greater than zero.
        /// </remarks>
        /// <param name="filename">
        /// The fully qualified name of the file.
        /// </param>
        /// <param name="overwrite">
        /// True to force an overwrite of an existing file and false otherwise.
        /// The method throws an exception if parameter <paramref name="overwrite"/>
        /// is <c>false</c> and provided file already exists.
        /// </param>
        /// <param name="length">
        /// The length of the new file to be adjusted.
        /// </param>
        /// <exception cref="ArgumentException">
        /// Either the provided filename is invalid or the provided length is less
        /// than zero.
        /// </exception>
        /// <exception cref="NativeException">
        /// Something went wrong while creating the new file. The property
        /// <see cref="NativeException.HResult"/> of the exception contains
        /// the detailed error code.
        /// </exception>
        public static void Create(String filename, Boolean overwrite, Int64 length)
        {
            if (String.IsNullOrWhiteSpace(filename))
            {
                throw new ArgumentException("File name must not be null or empty or only consists of white spaces.");
            }

            if (length < 0)
            {
                throw new ArgumentException($"Requested length for file \"{filename}\" must be greater than zero.");
            }

            Int32 nMode   = (Int32)(overwrite ? FileMode.CREATE_ALWAYS : FileMode.CREATE_NEW);
            Int32 nAccess = (Int32)FileAccess.GENERIC_WRITE;
            Int32 nShare  = (Int32)FileShare.FILE_SHARE_WRITE;
            Int32 nFlags  = (Int32)FileFlags.FILE_FLAG_NONE | (Int32)FileAttributes.FILE_ATTRIBUTE_NORMAL;

            IntPtr handle = AccessHandler.CreateFileW(filename, nAccess, nShare, IntPtr.Zero, nMode, nFlags, IntPtr.Zero);

            try
            {
                if (!AccessHandler.IsHandle(handle))
                {
                    throw new NativeException($"Creating of file \"{filename}\" has failed.", Marshal.GetHRForLastWin32Error());
                }

                if (length > 0)
                {
                    // Resize file up to requested file size.
                    if (!AccessHandler.SetFilePointerEx(handle, length, out Int64 result, MoveMethod.FILE_BEGIN))
                    {
                        throw new NativeException($"Changing length of file \"{filename}\" has failed.", Marshal.GetHRForLastWin32Error());
                    }

                    // According to docs this is required for changing current file size.
                    if (!AccessHandler.SetEndOfFile(handle))
                    {
                        throw new NativeException($"Writing length of file \"{filename}\" has failed.", Marshal.GetHRForLastWin32Error());
                    }
                }
            }
            finally
            {
                if (AccessHandler.IsHandle(handle))
                {
                    AccessHandler.CloseHandle(handle);
                }
            }
        }
Пример #4
0
    private Boolean OpenFile(String filename, FileMode mode, FileAccess access, FileShare share, FileFlags flags, FileAttributes attributes)
    {
        Int32 nMode   = (Int32)mode;
        Int32 nAccess = (Int32)access;
        Int32 nShare  = (Int32)share;
        Int32 nFlags  = (Int32)flags | (Int32)attributes;

        IntPtr handle = AccessHandler.CreateFileW(filename, nAccess, nShare, IntPtr.Zero, nMode, nFlags, IntPtr.Zero);

        if (!AccessHandler.IsHandle(handle))
        {
            return(false);
        }

        this.IsWritable = (access & FileAccess.GENERIC_WRITE) == FileAccess.GENERIC_WRITE;
        this.handle     = handle;
        this.filename   = filename;

        return(true);
    }
Пример #5
0
        public Boolean Flush()
        {
            Boolean result = true;

            if (this.IsValid)
            {
                try
                {
                    if (this.IsWritable && !AccessHandler.FlushFileBuffers(this.handle))
                    {
                        throw new NativeException("Flushing file buffers has failed.", Marshal.GetHRForLastWin32Error());
                    }
                }
                catch (Exception exception)
                {
                    result = false;
                    this.logger.Warning(MethodBase.GetCurrentMethod(), exception, this.GetDetail(nameof(this.filename), this.filename));
                }
            }

            return(result);
        }
Пример #6
0
        public Boolean Close()
        {
            Boolean result = true;

            if (this.IsValid)
            {
                try
                {
                    if (!AccessHandler.CloseHandle(this.handle))
                    {
                        throw new NativeException("Closing file handle has failed.", Marshal.GetHRForLastWin32Error());
                    }

                    this.handle = IntPtr.Zero;
                }
                catch (Exception exception)
                {
                    result = false;
                    this.logger.Warning(MethodBase.GetCurrentMethod(), exception, this.GetDetail(nameof(this.filename), this.filename));
                }
            }

            return(result);
        }
Пример #7
0
        /// <summary>
        /// Tries to obtain the length in byte of provided file.
        /// </summary>
        /// <remarks>
        /// This method tries to obtain the length of provided file and returns
        /// it if successful. The length returned by this method represents the
        /// number of bytes of that file.
        /// </remarks>
        /// <param name="filename">
        /// The fully qualified name of the file.
        /// </param>
        /// <returns>
        /// The length in byte of the file.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// The provided filename is invalid.
        /// </exception>
        /// <exception cref="NativeException">
        /// Something went wrong while obtaining the length of the file. The property
        /// <see cref="NativeException.HResult"/> of the exception contains
        /// the detailed error code.
        /// </exception>
        public static Int64 GetLength(String filename)
        {
            if (String.IsNullOrWhiteSpace(filename))
            {
                throw new ArgumentException("File name must not be null or empty or only consists of white spaces.");
            }

            Int32 nMode   = (Int32)FileMode.OPEN_EXISTING;
            Int32 nAccess = (Int32)FileAccess.GENERIC_READ;
            Int32 nShare  = (Int32)FileShare.FILE_SHARE_READ;
            Int32 nFlags  = (Int32)FileFlags.FILE_FLAG_NONE | (Int32)FileAttributes.FILE_ATTRIBUTE_NORMAL;

            IntPtr handle = AccessHandler.CreateFileW(filename, nAccess, nShare, IntPtr.Zero, nMode, nFlags, IntPtr.Zero);

            try
            {
                if (!AccessHandler.IsHandle(handle))
                {
                    throw new NativeException($"Accessing file \"{filename}\" for read has failed.", Marshal.GetHRForLastWin32Error());
                }

                if (!AccessHandler.GetFileSizeEx(handle, out Int64 length))
                {
                    throw new NativeException($"Obtaining length of file \"{filename}\" has failed.", Marshal.GetHRForLastWin32Error());
                }

                return(length);
            }
            finally
            {
                if (AccessHandler.IsHandle(handle))
                {
                    AccessHandler.CloseHandle(handle);
                }
            }
        }