linux 稀疏文件(Sparse File)-阿里云开发者社区

开发者社区> 长烟慢慢> 正文

linux 稀疏文件(Sparse File)

简介: 稀疏文件,这是UNIX类和NTFS等文件系统的一个特性。 开始时,一个稀疏文件不包含用户数据,也没有分配到用来存储用户数据的磁盘空间。当数据被写入稀疏文件时,NTFS逐渐地为其分配磁盘空间。
+关注继续查看
稀疏文件,这是UNIX类和NTFS等文件系统的一个特性。
开始时,一个稀疏文件不包含用户数据,也没有分配到用来存储用户数据的磁盘空间。当数据被写入稀疏文件时,NTFS逐渐地为其分配磁盘空间。一个稀疏文件有可能增长得很大。
稀疏文件以64KB(不同文件系统不同)为单位增量增长,因此磁盘上稀疏文件的大小总是64KB的倍数。
稀疏文件就是在文件中留有很多空余空间,留备将来插入数据使用。如果这些空余空间被ASCII码的NULL字符占据,并且这些空间相当大,那么,这个文件就被称为稀疏文件,而且,并不分配相应的磁盘块。 
这样,会产生一个问题,文件已被创建了,但相应的磁盘空间并未被分配,只有在有真正的数据插入进来时,才会被分配磁盘块,如果这时文件系统被占满了,那么对该文件的写操作就会失败。为防止这种情况,有两种办法:不产生稀疏文件或为稀疏文件留够空间。
在计算机科学方面,稀疏文件是文件系统中的一种文件存储方式,在创建一个文件的时候,就预先分配了文件需要的连续存储空间,其空间内部大多都还未被数据填充现在有很多文件系统都支持稀疏文件,包括大部分的Unix和NTFS 。
稀疏文件被普遍用来磁盘图像,数据库快照,日志文件,还有其他科学运用上。

1、WINDOWS中的稀疏文件

稀疏文件(Sparse File), 指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却一样的占用我们的空间,针对此,WINNT 3.51中的NTFS文件系统对此进行了优化,那些无用的0字节被用一定的算法压缩起来,使得这些0字节不再占用那么多的空间,在你声明一个很大的稀疏文件时(例如 100GB),这个文件实际上并不需要占用这么大的空间,因为里面大都是无用的0数据,那么,NTFS对稀疏文件的压缩算法可以释放这些无用的0字节空间, 可以说这是对磁盘占用空间以及效率的一种优化,记住,FAT32上并不支持稀疏文件的压缩(至少我在自己机子上测试得出如此结论)


这里,我们将粗略的介绍:

1,如何判断一个磁盘是否支持稀疏文件。
2,如何判断一个文件是否是稀疏文件。
3,如何产生一个稀疏文件。
4,假如系统支持稀疏文件,如何声明这个文件是稀疏文件。



1.1 判断一个磁盘是否是稀疏文件。

我们可以通过一个系统函数GetVolumeInformation 来判断某个磁盘是否支持稀疏文件的压缩。MSDN中的函数原型如下:

GetVolumeInformation

The GetVolumeInformation function retrieves information about a file system and volume that have a specified root directory.

BOOL GetVolumeInformation(
LPCTSTR lpRootPathName,
  LPTSTR lpVolumeNameBuffer,
  DWORD nVolumeNameSize,
  LPDWORD lpVolumeSerialNumber,
  LPDWORD lpMaximumComponentLength,
  LPDWORD lpFileSystemFlags,
  LPTSTR lpFileSystemNameBuffer,
  DWORD nFileSystemNameSize
);

我们只要把查询到的Flag 跟 FILE_SUPPORTS_SPARSE_FILES 位与(&),便可以知道该磁盘是否支持。





这是从我的工具集(toolset)里摘录的例子代码:

CHAR szVolName[MAX_PATH], szFsName[MAX_PATH]; DWORD dwSN, dwFSFlag, dwMaxLen, nWritten; BOOL bSuccess; HANDLE hFile; bSuccess = GetVolumeInformation(NULL, szVolName, MAX_PATH, &dwSN, &dwMaxLen, &dwFSFlag, szFsName, MAX_PATH); if (!bSuccess) { printf("errno:%d", GetLastError()); return -1; } printf("vol name:%s \t fs name:%s sn: %d.\n", szVolName, szFsName, dwSN); if (dwFSFlag&FILE_SUPPORTS_SPARSE_FILES) { printf("support sparse file.\n"); }else{ printf("no support sparse file.\n"); }
2.1 如何判断一个文件是否是稀疏文件。


  
  我们可以通过 GetFileInformationByHandle()函数来判断一个文件是否是稀疏文件。这是MSDN里面的定义。

The GetFileInformationByHandle function retrieves file information for the specified file.

BOOL GetFileInformationByHandle(
HANDLE hFile,
  LPBY_HANDLE_FILE_INFORMATION lpFileInformation
);
 
例子代码如下:
 

HANDLE hFile; BY_HANDLE_FILE_INFORMATION stFileInfo; //Open/create file to get the file handle hFile = CreateFile(); //Get the file information GetFileInformationByHandle(hFile, &stFileInfo); if(stFileInfo.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { //Sparse file }else{ //Not sparse file }
 
3.1, 如何产生一个稀疏文件并声明该文件是稀疏文件。
   大部分文件,在你改变它的EndOfFile的时候,中间的空白会被操作系统填0,也就是说,如果你用SetFilePointer() 和SetEndOfFile()来
产生一个很大的文件,那么这个文件它占用的是真正的磁盘空间,即使里面全是0,因为系统默认的会在DeviceIoControl()中的ControlCode里用
FSCTL_SET_ZERO_DATA标记,这个标记使得那些文件空洞被0所填充。为了节省磁盘空间,我们必须把一个文件声明为稀疏文件,以便让系统
把那些无用的0字节压缩,并释放相应的磁盘空间,方法如下:
 

hFile = CreateFile("tmp_file", GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); DWORD dwTemp; DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwTemp, NULL); SetFilePointer(hFile, 0x100000, NULL, FILE_BEGIN); WriteFile(hFile, "123", 3, &nWritten, NULL); SetEndOfFile(hFile); CloseHandle(hFile);
注意到FSCTL_SET_SPARSE这个标记了吗?正是这个标记,告诉系统该文件是稀疏文件,如果该文件所在的磁盘支持稀疏
文件的压缩,则系统会释放不必要的0字节空间。你可以用这个方法创建一个100GB得文件试一下(示例里是1M),记得右键看看文件属性
里的‘大小’和占用空间,它被声明为100GB,但是实际上那些0字节基本不占用空间,而你写入的“123”是占用实际的
磁盘空间的。
   注意:在FAT32得磁盘里,因为没有对SPARSE FILE得支持,所以您创建的空洞文件全部被填零,即使你声明它是一个稀疏
文件,也没有任何作用,您声明这个文件多大,它就占用多大的空间。
   另外,如果您编译 DeviceIoControl这个函数出现 "'FSCTL_SET_SPARSE' : undeclared identifier"之类的情况
请这样做:
#include <windows.h>
#define   _WIN32_WINNT         0x0501 
#include <Winioctl.h>

2、Linux文件空洞与稀疏文件

在UNIX文件操作中,文件位移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将延长该文件,并在文件中构成一个空洞。位于文件中但没有写过的字节都被设为0。
如果offset 比文件的当前长度更大,下一个写操作就会把文件“撑大(extend)” 在文件里创造“空洞(hole)”。没有被实际写入文件的所有字节由重复的0 表示。空洞是否占用硬盘空间是由文件系统(file system)决定的。



稀疏文件(Sparse File)
稀疏文件与其他普通文件基本相同,区别在于文件中的部分数据是全0,且这部分数据不占用磁盘空间。
下面是稀疏文件的创建与查看
[root@localhost ~]# dd if=/dev/zero of=sparse-file bs=1 count=1 seek=1024k
[root@localhost ~]# ls -l sparse-file
-rw-r--r-- 1 root root 1048577 Oct 15 17:50 sparse-file
[root@localhost ~]# du -sh sparse-file
8.0K sparse-file
[root@localhost ~]# cat anaconda-ks.cfg >> sparse-file
[root@localhost ~]# du -sh sparse-file
12Ksparse-file
[root@localhost ~]# du -sh anaconda-ks.cfg
12Kanaconda-ks.cfg
[root@localhost ~]#

文件系统存储稀疏文件时,inode索引节点中,只给出实际占用磁盘空间的block号,数据全0,且不占用磁盘空间的文件block并没有物理磁盘block号。

linux稀疏文件Inode数据块存储:
文件空洞部分不占用磁盘空间
文件所占用的磁盘空间仍然是连续的





版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9479 0
Makefile文件编写
源代码文件 main3.c 1 #include 2 #include "static_lib.h" 3 #include "fun.h" 4 5 int main(void){ 6 int a=2,b=3; 7 printf("add:%d s...
884 0
如何在函数计算中使用 Node.js 处理 multipart 文件上传请求
web 开发中我们经常会允许用户通过 HTTP POST 请求上传文档到服务器,本文将介绍在函数计算中基于 node.js 使用 multipart form-data 来实现文件上传服务。
2708 0
文件句柄(file handles) &amp; 文件描述符(file descriptors)
1.概述 在实际工作中会经常遇到一些bug,有些就需要用到文件句柄,文件描述符等概念,比如报错: too many open files, 如果你对相关知识一无所知,那么debug起来将会异常痛苦。
1521 0
6.2 file 写文件
#!/usr/bin/env python # -*- coding:utf-8 -*- #@Time      :2017/10/27 22:15 #@Author    :zhouyuyao #@File      :file_write.
569 0
js判断文件格式及大小
//上传文件大小以及格式验证 function getPhotoSize(obj){ photoExt=obj.
671 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13162 0
6.1 file 读文件
#!/usr/bin/env python # -*- coding:utf-8 -*- #@Time      :2017/10/27 21:54 #@Author    :zhouyuyao #@File      :file_demo1.
487 0
parseConf(配置文件解析器)
1 /****************************************************************************** 2 * 3 * parseConf(配置文件解析器) 4 * 5 * 1.
566 0
+关注
长烟慢慢
系统架构师
814
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载