예제 #1
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);
                }
            }
        }
예제 #2
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);
    }
예제 #3
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);
                }
            }
        }