Exemple #1
0
 public void ReturnsZeroForEmptyFile(FileOptions options)
 {
     using (SafeFileHandle handle = File.OpenHandle(GetTestFilePath(), FileMode.CreateNew, FileAccess.Write, options: options))
     {
         Assert.Equal(0, RandomAccess.GetLength(handle));
     }
 }
    public TroikaArchive(string path)
    {
        Path = path;

        _fileHandle = File.OpenHandle(
            path,
            FileMode.Open,
            FileAccess.Read,
            FileShare.Read,
            FileOptions.RandomAccess
            );
        _fileStream = new FileStream(_fileHandle, FileAccess.Read);
        _fileLength = RandomAccess.GetLength(_fileHandle);

        // Read the file table
        try
        {
            ReadFileTable(_fileHandle);
        }
        catch
        {
            _fileHandle.Dispose();
            throw;
        }
    }
Exemple #3
0
        public void ModifiesTheActualFileSize(FileOptions options)
        {
            using (SafeFileHandle handle = File.OpenHandle(GetTestFilePath(), FileMode.CreateNew, FileAccess.Write, options: options))
            {
                RandomAccess.SetLength(handle, FileSize);

                Assert.Equal(FileSize, RandomAccess.GetLength(handle));
            }
        }
Exemple #4
0
        private FileSystemMetadata GetFileSystemMetadata(FileSystemInfo info)
        {
            var result = new FileSystemMetadata
            {
                Exists    = info.Exists,
                FullName  = info.FullName,
                Extension = info.Extension,
                Name      = info.Name
            };

            if (result.Exists)
            {
                result.IsDirectory = info is DirectoryInfo || (info.Attributes & FileAttributes.Directory) == FileAttributes.Directory;

                // if (!result.IsDirectory)
                // {
                //    result.IsHidden = (info.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
                // }

                if (info is FileInfo fileInfo)
                {
                    result.Length = fileInfo.Length;

                    // Issue #2354 get the size of files behind symbolic links. Also Enum.HasFlag is bad as it boxes!
                    if ((fileInfo.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
                    {
                        try
                        {
                            using (var fileHandle = File.OpenHandle(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            {
                                result.Length = RandomAccess.GetLength(fileHandle);
                            }
                        }
                        catch (FileNotFoundException ex)
                        {
                            // Dangling symlinks cannot be detected before opening the file unfortunately...
                            _logger.LogError(ex, "Reading the file size of the symlink at {Path} failed. Marking the file as not existing.", fileInfo.FullName);
                            result.Exists = false;
                        }
                        catch (UnauthorizedAccessException ex)
                        {
                            _logger.LogError(ex, "Reading the file at {Path} failed due to a permissions exception.", fileInfo.FullName);
                        }
                    }
                }

                result.CreationTimeUtc  = GetCreationTimeUtc(info);
                result.LastWriteTimeUtc = GetLastWriteTimeUtc(info);
            }
            else
            {
                result.IsDirectory = info is DirectoryInfo;
            }

            return(result);
        }
Exemple #5
0
    /// <summary>
    /// 读取二进制文件。
    /// </summary>
    /// <param name="path">给定的文件路径。</param>
    /// <param name="fileOffset">给定的读取偏移量。</param>
    /// <returns>返回字节数组。</returns>
    public static byte[] ReadBinaryFile(this string path, long fileOffset)
    {
        using (var handle = File.OpenHandle(path))
        {
            var length = RandomAccess.GetLength(handle);
            var buffer = new byte[length - fileOffset];

            var readLength = RandomAccess.Read(handle, buffer, fileOffset);
            return(buffer);
        }
    }
Exemple #6
0
        public void ReadFromBeyondEndOfFileReturnsZero(FileOptions options)
        {
            string filePath = GetTestFilePath();

            File.WriteAllBytes(filePath, new byte[100]);

            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
            {
                long eof = RandomAccess.GetLength(handle);
                Assert.Equal(0, RandomAccess.Read(handle, new byte[1], fileOffset: eof + 1));
            }
        }
Exemple #7
0
        public void ReturnsExactSizeForNonEmptyFiles(FileOptions options)
        {
            const int fileSize = 123;
            string    filePath = GetTestFilePath();

            File.WriteAllBytes(filePath, new byte[fileSize]);

            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
            {
                Assert.Equal(fileSize, RandomAccess.GetLength(handle));
            }
        }
Exemple #8
0
        public async Task ReadFromBeyondEndOfFileReturnsZeroAsync(FileOptions options)
        {
            string filePath = GetTestFilePath();

            File.WriteAllBytes(filePath, new byte[100]);

            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
            {
                long eof = RandomAccess.GetLength(handle);
                Assert.Equal(0, await RandomAccess.ReadAsync(handle, new Memory <byte>[] { new byte[1] }, fileOffset: eof + 1));
            }
        }
Exemple #9
0
        public void AllowsForShrinking(FileOptions options)
        {
            using (SafeFileHandle handle = File.OpenHandle(GetTestFilePath(), FileMode.CreateNew, FileAccess.Write, options: options))
            {
                RandomAccess.SetLength(handle, FileSize);
                Assert.Equal(FileSize, RandomAccess.GetLength(handle));

                RandomAccess.SetLength(handle, FileSize / 2);
                Assert.Equal(FileSize / 2, RandomAccess.GetLength(handle));

                RandomAccess.SetLength(handle, 0);
                Assert.Equal(0, RandomAccess.GetLength(handle));
            }
        }
Exemple #10
0
        public void WriteBeyondEndOfFileExtendsTheFile(FileOptions options)
        {
            string filePath = GetTestFilePath();

            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.CreateNew, FileAccess.Write, options: options))
            {
                Assert.Equal(0, RandomAccess.GetLength(handle));
                RandomAccess.Write(handle, new ReadOnlyMemory <byte>[] { new byte[1] {
                                                                             1
                                                                         } }, fileOffset: 1);
                Assert.Equal(2, RandomAccess.GetLength(handle));
            }

            Assert.Equal(new byte[] { 0, 1 }, File.ReadAllBytes(filePath));
        }
Exemple #11
0
 public void ReturnsActualLengthForDevices(FileOptions options)
 {
     // Both File.Exists and Path.Exists return false when "\\?\PhysicalDrive0" exists
     // that is why we just try and swallow the exception when it occurs.
     // Exception can be also thrown when the file is in use (#73925).
     try
     {
         using (SafeFileHandle handle = File.OpenHandle(@"\\?\PhysicalDrive0", FileMode.Open, options: options))
         {
             long length = RandomAccess.GetLength(handle);
             Assert.True(length > 0);
         }
     }
     catch (IOException) { }
 }
Exemple #12
0
        public async Task WriteBeyondEndOfFileExtendsTheFileAsync(FileOptions options)
        {
            string filePath = GetTestFilePath();

            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.CreateNew, FileAccess.Write, options: options))
            {
                Assert.Equal(0, RandomAccess.GetLength(handle));
                await RandomAccess.WriteAsync(handle, new byte[1] {
                    1
                }, fileOffset : 1);

                Assert.Equal(2, RandomAccess.GetLength(handle));
            }

            Assert.Equal(new byte[] { 0, 1 }, await File.ReadAllBytesAsync(filePath));
        }
        /// <summary>Read the database for the specified terminal from the specified directory.</summary>
        /// <param name="term">The identifier for the terminal.</param>
        /// <param name="directoryPath">The path to the directory containing terminfo database files.</param>
        /// <returns>The database, or null if it could not be found.</returns>
        internal static Database?ReadDatabase(string?term, string?directoryPath)
        {
            if (string.IsNullOrEmpty(term) || string.IsNullOrEmpty(directoryPath))
            {
                return(null);
            }

            Span <char>    stackBuffer = stackalloc char[256];
            SafeFileHandle?fd;

            if (!TryOpen(string.Create(null, stackBuffer, $"{directoryPath}/{term[0]}/{term}"), out fd) &&       // /directory/termFirstLetter/term      (Linux)
                !TryOpen(string.Create(null, stackBuffer, $"{directoryPath}/{(int)term[0]:X}/{term}"), out fd))  // /directory/termFirstLetterAsHex/term (Mac)
            {
                return(null);
            }

            using (fd)
            {
                // Read in all of the terminfo data
                long      termInfoLength    = RandomAccess.GetLength(fd);
                const int MaxTermInfoLength = 4096; // according to the term and tic man pages, 4096 is the terminfo file size max
                const int HeaderLength      = 12;
                if (termInfoLength <= HeaderLength || termInfoLength > MaxTermInfoLength)
                {
                    throw new InvalidOperationException(SR.IO_TermInfoInvalid);
                }

                byte[] data       = new byte[(int)termInfoLength];
                long   fileOffset = 0;
                do
                {
                    int bytesRead = RandomAccess.Read(fd, new Span <byte>(data, (int)fileOffset, (int)(termInfoLength - fileOffset)), fileOffset);
                    if (bytesRead == 0)
                    {
                        throw new InvalidOperationException(SR.IO_TermInfoInvalid);
                    }

                    fileOffset += bytesRead;
                } while (fileOffset < termInfoLength);

                // Create the database from the data
                return(new Database(term, data));
            }
        }
Exemple #14
0
        /// <inheritdoc />
        protected override FileMetadata GetFileInfo(string path)
        {
            var fileInfo = new FileInfo(path);
            var length   = fileInfo.Length;

            // This may or may not be fixed in .NET 6, but looks like it will not https://github.com/dotnet/aspnetcore/issues/34371
            if ((fileInfo.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
            {
                using var fileHandle = File.OpenHandle(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                length = RandomAccess.GetLength(fileHandle);
            }

            return(new FileMetadata
            {
                Exists = fileInfo.Exists,
                Length = length,
                LastModified = fileInfo.LastWriteTimeUtc
            });
        }
Exemple #15
0
        private static bool CompareTimeZoneFile(string filePath, byte[] buffer, byte[] rawData)
        {
            try
            {
                // bufferSize == 1 used to avoid unnecessary buffer in FileStream
                using (SafeFileHandle sfh = File.OpenHandle(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    long fileLength = RandomAccess.GetLength(sfh);
                    if (fileLength == rawData.Length)
                    {
                        int index = 0;
                        int count = rawData.Length;

                        while (count > 0)
                        {
                            int n = RandomAccess.Read(sfh, buffer.AsSpan(index, count), index);
                            if (n == 0)
                            {
                                ThrowHelper.ThrowEndOfFileException();
                            }

                            int end = index + n;
                            for (; index < end; index++)
                            {
                                if (buffer[index] != rawData[index])
                                {
                                    return(false);
                                }
                            }

                            count -= n;
                        }

                        return(true);
                    }
                }
            }
            catch (IOException) { }
            catch (SecurityException) { }
            catch (UnauthorizedAccessException) { }

            return(false);
        }
        public static MemoryMappedFile CreateFromFile(string path, FileMode mode, string?mapName, long capacity,
                                                      MemoryMappedFileAccess access)
        {
            ArgumentNullException.ThrowIfNull(path);

            if (mapName != null && mapName.Length == 0)
            {
                throw new ArgumentException(SR.Argument_MapNameEmptyString);
            }

            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_PositiveOrDefaultCapacityRequired);
            }

            if (access < MemoryMappedFileAccess.ReadWrite ||
                access > MemoryMappedFileAccess.ReadWriteExecute)
            {
                throw new ArgumentOutOfRangeException(nameof(access));
            }

            if (mode == FileMode.Append)
            {
                throw new ArgumentException(SR.Argument_NewMMFAppendModeNotAllowed, nameof(mode));
            }
            if (mode == FileMode.Truncate)
            {
                throw new ArgumentException(SR.Argument_NewMMFTruncateModeNotAllowed, nameof(mode));
            }
            if (access == MemoryMappedFileAccess.Write)
            {
                throw new ArgumentException(SR.Argument_NewMMFWriteAccessNotAllowed, nameof(access));
            }

            bool existed = mode switch
            {
                FileMode.Open => true, // FileStream ctor will throw if the file doesn't exist
                FileMode.CreateNew => false,
                _ => File.Exists(path)
            };
            SafeFileHandle fileHandle = File.OpenHandle(path, mode, GetFileAccess(access), FileShare.Read, FileOptions.None);
            long           fileSize   = 0;

            if (mode is not(FileMode.CreateNew or FileMode.Create))  // the file is brand new and it's empty
            {
                try
                {
                    fileSize = RandomAccess.GetLength(fileHandle);
                }
                catch
                {
                    fileHandle.Dispose();
                    throw;
                }
            }

            if (capacity == 0 && fileSize == 0)
            {
                CleanupFile(fileHandle, existed, path);
                throw new ArgumentException(SR.Argument_EmptyFile);
            }

            if (capacity == DefaultSize)
            {
                capacity = fileSize;
            }

            SafeMemoryMappedFileHandle?handle;

            try
            {
                handle = CreateCore(fileHandle, mapName, HandleInheritability.None,
                                    access, MemoryMappedFileOptions.None, capacity, fileSize);
            }
            catch
            {
                CleanupFile(fileHandle, existed, path);
                throw;
            }

            Debug.Assert(handle != null);
            Debug.Assert(!handle.IsInvalid);
            return(new MemoryMappedFile(handle, fileHandle, false));
        }
Exemple #17
0
 protected override long MethodUnderTest(SafeFileHandle handle, byte[] bytes, long fileOffset)
 => RandomAccess.GetLength(handle);