Esempio n. 1
0
        public void AtomicWrite_ReplacingExistingReadOnlyFile_Throws()
        {
            var path = BaseDir.CreateFile("test.txt");

            SafeFile.SetReadOnly(path);

            Should.Throw <UnauthorizedAccessException>(() =>
                                                       SafeFile.AtomicWrite(path, tmpPath => tmpPath.ToNPath().CreateFile()));
        }
Esempio n. 2
0
        public void AtomicWrite_WithEmptyAction_ShouldDoNothing()
        {
            var path = BaseDir.CreateFile("test.txt");

            SafeFile.AtomicWrite(path, tmpPath => { });

            path.FileExists().ShouldBeTrue();
            (path + SafeFile.TmpExtension).ToNPath().FileExists().ShouldBeFalse();
            (path + SafeFile.BakExtension).ToNPath().FileExists().ShouldBeFalse();
        }
Esempio n. 3
0
        public void AtomicWrite_WithExistingReadOnlyTempAndBakFiles_OverwritesFilesAndOperatesNormally()
        {
            var path   = BaseDir.Combine("test.txt").WriteAllText("test");
            var temp   = (path + SafeFile.TmpExtension).ToNPath().CreateFile();
            var backup = (path + SafeFile.BakExtension).ToNPath().CreateFile();

            SafeFile.SetReadOnly(temp);
            SafeFile.SetReadOnly(backup);

            SafeFile.AtomicWrite(path, tmpPath => tmpPath.ToNPath().WriteAllText("new"));

            temp.FileExists().ShouldBeFalse();
            backup.FileExists().ShouldBeFalse();
            path.ReadAllText().ShouldBe("new");
        }
Esempio n. 4
0
        static bool OverwriteFileIfChanged(FormatItem formatItem, IEnumerable <string> lines, EndOfLine eol)
        {
            // write to a buffer so we can do an exact comparison vs the file already on disk. let's avoid generating io writes if
            // there is no actual change. but we need to have the raw bytes so that differences in encoding and EOL's are not masked.

            var newFileBuffer = new MemoryStream();

            WriteLines(newFileBuffer, lines, formatItem.EditorConfig.Charset, eol);
            var newFileBytes  = newFileBuffer.GetBuffer();
            var newFileLength = (int)newFileBuffer.Length;                     // not newFileBytes.Length!

            var match = new FileInfo(formatItem.Path).Length == newFileLength; // do cheap length check first

            if (match)
            {
                var oldFileBytes = File.ReadAllBytes(formatItem.Path);

                // must do the byte compare vs disk
                for (var i = 0; i < newFileLength; ++i)
                {
                    if (newFileBytes[i] != oldFileBytes[i])
                    {
                        match = false;
                        break;
                    }
                }
            }

            // ok we have to write it
            if (!match)
            {
                // TODO: copy the permission bits over ($mode & 0777) to the new file
                // TODO: backup under ./Temp/Format (subfolders? replace folder names with _?) configurable via a new FormatContext.BackupRoot
                SafeFile.AtomicWrite(formatItem.Path, writePath =>
                {
                    using (var writeFile = File.OpenWrite(writePath))
                        writeFile.Write(newFileBytes, 0, newFileLength);
                });
            }

            return(!match);
        }