代码之家  ›  专栏  ›  技术社区  ›  Minimus Heximus

在不打开文件的情况下更改文件的大小

  •  0
  • Minimus Heximus  · 技术社区  · 6 年前

    std::filesystem::resize_file 在C++中,可以在不打开文件的情况下更改文件的大小。

    我认为以文件流的形式打开一个文件并用新的大小再次保存它会比较慢。

    1 回复  |  直到 6 年前
        1
  •  5
  •   Matthew Watson    6 年前

    使用 FileStream.SetLength() 会尽快赶到的。

    它最终调用windowsapi来设置文件的长度,与 std::filesystem::resize_file() .

    所以你只需要做这样的事情,它会足够快:

    using (var file = File.Open(myFilePath, FileMode.Open))
    {
        file.SetLength(myRequiredFileSize);
    }
    

        private void SetLengthCore(long value)
        {
            Contract.Assert(value >= 0, "value >= 0");
            long origPos = _pos;
    
            if (_exposedHandle)
                VerifyOSHandlePosition();
            if (_pos != value)
                SeekCore(value, SeekOrigin.Begin);
            if (!Win32Native.SetEndOfFile(_handle)) {
                int hr = Marshal.GetLastWin32Error();
                if (hr==__Error.ERROR_INVALID_PARAMETER)
                    throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_FileLengthTooBig"));
                __Error.WinIOError(hr, String.Empty);
            }
            // Return file pointer to where it was before setting length
            if (origPos != value) {
                if (origPos < value)
                    SeekCore(origPos, SeekOrigin.Begin);
                else
                    SeekCore(0, SeekOrigin.End);
            }
        }
    

    (注意 SeekCore() SetFilePointer() 函数。)

    另外,Windows API函数 SetEndOfFile() If the file is extended, the contents of the file between the old end of the file and the new end of the file are not defined.

    作为测试,我尝试了以下代码:

    using System;
    using System.Diagnostics;
    using System.IO;
    
    namespace Demo
    {
        public class Program
        {
            public static void Main()
            {
                string filename = @"e:\tmp\test.bin";
                File.WriteAllBytes(filename, new byte[0]); // Create empty file.
    
                var sw = Stopwatch.StartNew();
    
                using (var file = File.Open(filename, FileMode.Open))
                {
                    file.SetLength(1024*1024*1024);
                }
    
                Console.WriteLine(sw.Elapsed);
            }
        }
    }
    

    我的硬盘是硬盘,不是SSD。

    00:00:00.0003574

    因此,将文件扩展到1GB只需不到百分之一秒的时间。