Example #1
0
        private async Task TransferFileAsync(IFileOperationsExecuter sourceFileOps, SlimFileInfo sourceFile, IFileOperationsExecuter targetFileOps, SlimFileSystemInfo target, string targetDirectory)
        {
            if (target == null)
            {
                if (this.VerboseLogging)
                {
                    this.LogDebug($"{sourceFile.Name} does not exist in {targetDirectory}.");
                }
            }

            var targetFile = target as SlimFileInfo;

            if (targetFile != null)
            {
                this.LogDebug($"{sourceFile.Name} already exists in {targetDirectory}.");

                this.LogDebug($"Source timestamp: {sourceFile.LastWriteTimeUtc}, Target timestamp: {targetFile.LastWriteTimeUtc}");
                this.LogDebug($"Source size: {sourceFile.Size}, Target size: {targetFile.Size}");
                if (sourceFile.LastWriteTimeUtc == targetFile.LastWriteTimeUtc && sourceFile.Size == targetFile.Size)
                {
                    this.LogDebug($"Size and timestamp are the same; skipping {sourceFile.Name}...");
                    return;
                }
            }
            else if (target != null)
            {
                this.LogDebug($"{sourceFile.Name} is a file in {sourceFile.DirectoryName}, but a directory in {targetDirectory}.");

                this.LogDebug($"Deleting directory {target.FullName}...");
                await targetFileOps.DeleteDirectoriesAsync(new[] { target.FullName }).ConfigureAwait(false);
            }
            else
            {
                if (!string.IsNullOrEmpty(targetDirectory))
                {
                    await targetFileOps.CreateDirectoryAsync(targetDirectory).ConfigureAwait(false);
                }
            }

            var targetFileName = PathEx.Combine(targetDirectory, sourceFile.Name).Replace(sourceFileOps.DirectorySeparator, targetFileOps.DirectorySeparator);

            this.LogDebug($"Transferring {sourceFile.Name} to {targetDirectory}...");

            using (var sourceStream = await sourceFileOps.OpenFileAsync(sourceFile.FullName, FileMode.Open, FileAccess.Read).ConfigureAwait(false))
                using (var targetStream = await targetFileOps.OpenFileAsync(targetFileName, FileMode.Create, FileAccess.Write).ConfigureAwait(false))
                {
                    await sourceStream.CopyToAsync(targetStream).ConfigureAwait(false);
                }
        }
        private static bool IsFileContentsUpToDate(FileData oldFileData)
        {
            // TODO(rpaquay): The following File.Exists and File.GetLastWriteTimUtc are expensive operations.
            //  Given we have FileSystemChanged events when files change on disk, we could be smarter here
            // and avoid 99% of these checks in common cases.
            var fi = new SlimFileInfo(oldFileData.FileName.FullPathName);

            if (fi.Exists)
            {
                var contents = oldFileData.Contents;
                if (contents != null)
                {
                    if (fi.LastWriteTimeUtc == contents.UtcLastModified)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #3
0
        private FileContents ReadFile(FullPathName 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);
            }
        }
Example #4
0
 public FileInfoSnapshot(FullPath path)
 {
     _fileInfo = new SlimFileInfo(path);
 }
Example #5
0
 public FileInfoSnapshot(SlimFileInfo fileInfo)
 {
     _fileInfo = fileInfo;
 }