private static SafeHeapBlockHandle ReadFileWorker(SlimFileInfo fileInfo, int trailingByteCount) { using ( var fileHandle = NativeMethods.CreateFile(fileInfo.FullPathName.FullName, NativeAccessFlags.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero)) { if (fileHandle.IsInvalid) { throw new Win32Exception(); } // Note: We are limited to 2GB files by design. var len = (int)fileInfo.Length; var heap = HeapAllocStatic.Alloc(len + trailingByteCount); var bytesRead = new int[1]; if (!NativeMethods.ReadFile(fileHandle, heap.Pointer, len, bytesRead, null)) { throw new Win32Exception(); } if (bytesRead[0] != len) { throw new Exception("File read operation didn't read the whole file"); } return(heap); } }
private static SafeHeapBlockHandle ReadFileWorker(SlimFileInfo fileInfo, int trailingByteCount) { using ( var fileHandle = NativeMethods.CreateFile(fileInfo.FullPath.Value, NativeAccessFlags.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero)) { if (fileHandle.IsInvalid) throw new Win32Exception(); // Note: We are limited to 2GB files by design. int maxLen = Int32.MaxValue - trailingByteCount; if (fileInfo.Length >= maxLen) { Logger.LogWarning("File too big, truncated to {0} bytes", maxLen); } var len = (int)Math.Min(maxLen, fileInfo.Length); var heap = HeapAllocStatic.Alloc(len + trailingByteCount); var bytesRead = new int[1]; if (!NativeMethods.ReadFile(fileHandle, heap.Pointer, len, bytesRead, null)) throw new Win32Exception(); if (bytesRead[0] != len) throw new Exception("File read operation didn't read the whole file"); return heap; } }
private static SafeHeapBlockHandle ReadFileWorker(SlimFileInfo fileInfo, int trailingByteCount) { using ( var fileHandle = NativeMethods.CreateFile(fileInfo.FullPath.Value, NativeAccessFlags.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero)) { if (fileHandle.IsInvalid) { throw new Win32Exception(); } // Note: We are limited to 2GB files by design. int maxLen = Int32.MaxValue - trailingByteCount; if (fileInfo.Length >= maxLen) { Logger.LogWarning("File too big, truncated to {0} bytes", maxLen); } var len = (int)Math.Min(maxLen, fileInfo.Length); var heap = HeapAllocStatic.Alloc(len + trailingByteCount); var bytesRead = new int[1]; if (!NativeMethods.ReadFile(fileHandle, heap.Pointer, len, bytesRead, null)) { throw new Win32Exception(); } if (bytesRead[0] != len) { throw new Exception("File read operation didn't read the whole file"); } return(heap); } }
private FileContents ReadFile(FullPath fullName) { try { var fileInfo = new SlimFileInfo(fullName); const int trailingByteCount = 2; var block = NativeFile.ReadFileNulTerminated(fileInfo, trailingByteCount); var contentsByteCount = (int)block.ByteLength - trailingByteCount; // Padding added by ReadFileNulTerminated var kind = NativeMethods.Text_GetKind(block.Pointer, contentsByteCount); switch (kind) { case NativeMethods.TextKind.Ascii: return new AsciiFileContents(new FileContentsMemory(block, 0, contentsByteCount), fileInfo.LastWriteTimeUtc); case NativeMethods.TextKind.AsciiWithUtf8Bom: const int utf8BomSize = 3; return new AsciiFileContents(new FileContentsMemory(block, utf8BomSize, contentsByteCount - utf8BomSize), fileInfo.LastWriteTimeUtc); case NativeMethods.TextKind.Utf8WithBom: var utf16Block = Conversion.UTF8ToUnicode(block); block.Dispose(); return new UTF16FileContents(new FileContentsMemory(utf16Block, 0, utf16Block.ByteLength), fileInfo.LastWriteTimeUtc); case NativeMethods.TextKind.Unknown: default: // TODO(rpaquay): Figure out a better way to detect encoding. //Logger.Log("Text Encoding of file \"{0}\" is not recognized.", fullName); return new AsciiFileContents(new FileContentsMemory(block, 0, contentsByteCount), fileInfo.LastWriteTimeUtc); //throw new NotImplementedException(string.Format("Text Encoding of file \"{0}\" is not recognized.", fullName)); } } catch (Exception e) { Logger.LogException(e, "Error reading content of text file \"{0}\", skipping file.", fullName); return StringFileContents.Empty; } }
/// <summary> /// Note: For testability, this function should be called through <see cref="IFileSystem"/>. /// </summary> public static SafeHeapBlockHandle ReadFileNulTerminated(SlimFileInfo fileInfo, int trailingByteCount) { var result = ReadFileWorker(fileInfo, trailingByteCount); var trailingPtr = result.Pointer.ToInt64() + result.ByteLength - trailingByteCount; for (var i = 0; i < trailingByteCount; i++) { Marshal.WriteByte(new IntPtr(trailingPtr + i), 0); } return result; }
/// <summary> /// Note: For testability, this function should be called through <see cref="IFileSystem"/>. /// </summary> public static SafeHeapBlockHandle ReadFileNulTerminated(SlimFileInfo fileInfo, int trailingByteCount) { var result = ReadFileWorker(fileInfo, trailingByteCount); var trailingPtr = result.Pointer.ToInt64() + result.ByteLength - trailingByteCount; for (var i = 0; i < trailingByteCount; i++) { Marshal.WriteByte(new IntPtr(trailingPtr + i), 0); } return(result); }
private static SafeHeapBlockHandle ReadFileWorker(SlimFileInfo fileInfo, int trailingByteCount) { using ( var fileHandle = NativeMethods.CreateFile(fileInfo.FullPathName.FullName, NativeAccessFlags.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero)) { if (fileHandle.IsInvalid) throw new Win32Exception(); // Note: We are limited to 2GB files by design. var len = (int)fileInfo.Length; var heap = HeapAllocStatic.Alloc(len + trailingByteCount); var bytesRead = new int[1]; if (!NativeMethods.ReadFile(fileHandle, heap.Pointer, len, bytesRead, null)) throw new Win32Exception(); if (bytesRead[0] != len) throw new Exception("File read operation didn't read the whole file"); return heap; } }
public FileInfoSnapshot(FullPath path) { _fileInfo = new SlimFileInfo(path); }