/// <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); } } }
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); }
/// <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); } } }