草庐IT

1s 创建100G文件,最快的方法是?

Linux开发那些事儿 2023-03-28 原文

在我们日常工作中,为了验证开发的功能,比如:文件上传功能或者算法的处理效率等,经常需要一些大文件进行测试,有时在四处找了一顿之后,发现竟然没有一个合适的,虽然 Linux 中也有一些命令比如:vim、touch 等可以创建文件,但是如果需要一个 100G 或者 1T 的大文件,这些命令就显得力不从心,此时就需要能快速创建大文件命令,接下来将介绍这些命令的常见用法、命令之间的差异、以及使用时如何选择

dd

dd 命令的语法如下

dd if=[source] of=[destination] bs=[block-size] count=[counter]

source 读取并拷贝内容到 destinationsourcedestination 都是文件,前者是读取的文件,后者是写入的文件

bs 表示块的大小,单位是字节,后缀中带了字母 B的换算单位都是 1000, 比如: 1KB = 1000 Bytes 1MB = 1000 * 1000 Bytes 1GB = 1000 * 1000 * 1000 Bytes

后缀省略了字母 B的换算单位是 1024, 比如: 1K = 1024 Bytes 1M = 1024 * 1024 Bytes 1G = 1024 * 1024 * 1024 Bytes

count 表示块的数量,表示 dd 命令需要执行多少次读取并写入的操作

bs 乘以 count 其实就表示目标文件的大小,也即需要创建的文件的大小,比如:下面的命令可以创建一个 10G 大小的文件

[root@localhost dd_cmd]# dd if=/dev/zero of=testfile bs=1G count=10
记录了10+0 的读入
记录了10+0 的写出
10737418240字节(11 GB)已复制,8.61643 秒,1.2 GB/秒
[root@localhost dd_cmd]# du -h testfile  
10G     testfile
[root@localhost dd_cmd]# 

上面的命令表示从 /dev/zero文件每次读取 1G大小的数据并写入当前目录中的 testfile 文件, bs=1G count=10 表示块大小是1G,总共有10个块, 所以目标文件最终的大小是: 1G * 10 = 10G

/dev/zero 是一个特殊的字符设备文件,当读取它的时候,它会返回空数据,这里表示从 /dev/zero读取空的数据写入 testfile

命令 du -h testfile 的结果也说明了 testfile 大小是 10G

从结果可以得知,用 dd 命令创建一个 10G 大小的文件花费了约 8.6 秒

yes

前面的 dd 命令创建的是空字符的文件,如果想文件中包含自定义的字符,可以使用 yes 命令,它的作用是循环输出一行指定的字符串,直到进程结束,为了控制文件的大小并打破循环,我们借助 head 命令来实现,使用 yes 命令创建包含指定内容文件的语法如下

yes [string] | head -c [size of file] > [name of file]

string 是写入文件每一行的字符串

head -c [size of file] 是接收指定大小的字符串,单位是字节,后面也可以接 KKBMMBGGB等单位

下面的实例是往 yesfile 文件写入,每行的内容是: this is a test content , 一直到文件大小达到 10G

[root@localhost dd_cmd]# time yes "this is a test content" | head -c 10G > yesfile

real    0m11.266s
user    0m8.898s
sys     0m13.217s
[root@localhost dd_cmd]# du -h yesfile  
10G     yesfile

从结果可以看出,yes 命令创建一个 10G 的文件花费了 13.2 秒,比 dd 命令慢

fallocate

fallocate 命令使用下面的语法 创建大文件

fallocate -l [size of file] [name of file]

-l 选项表示文件大小,单位是字节,后面可以接 KKBMMBGGB等单位

下面的命令是创建一个 10G 大小的文件

[root@localhost dd_cmd]# time fallocate -l 10G allocatefile

real    0m0.002s
user    0m0.000s
sys     0m0.003s
[root@localhost dd_cmd]# du -h allocatefile  
10G     allocatefile

上述的 time 命令只是为了统计创建文件的时间,从结果可以看出:fallocate命令创建一个 10G 大小的文件竟然只花费了 0.003 秒

命令 du -h allocatefile 是查看创建的文件大小,从结果可知,allocatefile 文件大小确实是 10G

truncate

truncate 命令是缩小或者扩展文件至指定大小,它的语法如下:

truncate -s [file-size] [name of the file]

-s 选项表示文件大小,单位是字节,跟 fallocate 命令一样,后面可以接 KKBMMBGGB等单位

下面是使用 truncate 命令创建一个 10G的文件的示例

[root@localhost dd_cmd]# time truncate -s 10G truncatefile

real    0m0.002s
user    0m0.000s
sys     0m0.002s
[root@localhost dd_cmd]# du -h truncatefile 
0       truncatefile

从结果可以得到,truncate 命令 创建一个 10G的文件也只花费了 0.002 秒,和 fallocate 差不多

但是, du -h truncatefile 命令的结果表明 truncatefile 大小为 0

原因是 truncate 命令 创建的是一个稀疏文件而不是实际的文件 ,稀疏文件不会占用磁盘空间

注意:fallocate 命令只支持 btrfs、ext4、 ocfs2、xfs 这几种文件系统,而 truncate 命令支持所有的现代文件系统

创建速度的差异

从上面的几个实例可以看出,同样是创建一个 10G的文件, fallocatetruncate 命令只需要不到 0.1 秒的时间,但是 dd 命令需要 8.6 秒的时间,yes 命令需要 13.2 秒,这中间相差了几百倍,为什么会有这么大的差别呢?

fallocate 将空间分配给文件,但是不会往文件中写入任何数据

truncate 创建的是稀疏文件,和 fallocate 一样,它也不会往文件中写入任何数据

ddyes 都有写文件操作,而这需要大量的 IO 时间,所以同样创建 10G 的文件,它们比 fallocatetruncate 要慢很多

如何选择

ddyesfallocatetruncate 这几个命令都可以创建大文件, 在日常的使用中,我们该如何选择呢 ?

对速度没有很高的要求的情况下,一般首选 dd ,如果希望创建的文件中写入自定义的内容的话,使用 yes

如果想快速的创建大文件,比如 1 秒内创建一个 100G 的文件,选择 fallocatetruncate ,如果还需要确保文件是实际占用磁盘空间的话,就只剩下 fallocate 可选了

大部分情况下,fallocate 都能满足要求,所以不想仔细分析的话,使用 fallocate 就行了

小结

本文介绍了Linux下创建大文件的几种方法,并对所提供的方法进行了比较,最后提供了如何选择使用哪种方法的一些建议,文中只对 ddyesfallocatetruncate 命令做了简要的说明,更多的介绍请参考 man 文档

有关1s 创建100G文件,最快的方法是?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  4. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  5. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  6. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  7. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  8. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  9. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  10. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

随机推荐