c# - 在不打开文件的情况下更改文件的大小
问题描述
在std::filesystem::resize_file
C++ 中,可以在不打开文件的情况下更改文件的大小。
C#中是否有任何类似的功能,允许在不打开文件的情况下更改文件的大小?
我认为将文件作为 FileStream 打开并以新大小再次保存会更慢。
解决方案
使用FileStream.SetLength()
将尽可能快。
它最终调用 Windows API 来设置文件的长度,与 std::filesystem::resize_file()
.
所以你只需要做这样的事情,它就会足够快:
using (var file = File.Open(myFilePath, FileMode.Open))
{
file.SetLength(myRequiredFileSize);
}
FileStream.SetLength() 的实现是:
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()
只调用 Windows APISetFilePointer()
函数。)
这样做不会将文件读入内存。
此外,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);
}
}
}
我的 E:\ 驱动器是硬盘驱动器,而不是 SSD。
输出是:00:00:00.0003574
因此,将文件扩展至 1GB 只需不到百分之一秒。
推荐阅读
- http-live-streaming - hls 视频:为什么片段长度和目标持续时间之间存在差异?
- python - 将模型保存在单独的线程中
- xamarin.forms - Xamarin UITest 后门可以在 iOS 上返回值吗?
- python - 在其他人代码中对 numpy 数组进行操作
- r - 与上限函数的不一致
- asp.net - 某些下载的 PDF 会导致上传错误 ASP.net
- android - Agora React-Native No Video Feed (Audio Only) 在较新的 Android 设备上部署的应用程序(是 S10,Pixel 3)
- python - 如何在 Python 中使用 RegEx 获取两个带换行符的字符串之间的字符串
- python - 在转换第三列时将 excel 转换为 pdf 问题
- excel - 如何创建仅显示过去 4 周的动态图表?