在UNIX/LINUX系统中,文件位移量可以大于文件的当前长度,这种情况下向文件中写入数据就会产生文件空洞(hole),这些没写入数据的文件空洞部分默认会被0填满。虽然这些文件空洞并没有实际的数据,但是它们仍然占据硬盘空间。

  在Windows下同样支持这种文件空洞,以下简单的代码产生一个6KB的空洞文件:

#include <afx.h>
#include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[])
{
CFile testFile(_T("D:\\test"), CFile::modeCreate | CFile::modeWrite);
CHAR buff[];
memset(buff, , );
testFile.Write(buff, );
testFile.Seek( * , CFile::begin);
memset(buff, , );
testFile.Write(buff, );
testFile.Seek( * , CFile::begin);
memset(buff, , );
testFile.Write(buff, );
testFile.Close();
return ;
}

  用Sublime Text2打开,可以发现中间两部分是NULL(0),这就是文件空洞

  从代码地图上可以看到此文件有3KB是空的:

  

  Windows下的NTFS文件系统还支持文件空洞的压缩,那些0都是无用的数据,却又占据了空间资源,NTFS文件空洞的压缩算法可以释放这些0字节的空间。这种文件被称为稀疏文件,通过指定DeviceIoControl函数

BOOL WINAPI DeviceIoControl(
_In_ HANDLE hDevice,
_In_ DWORD dwIoControlCode,
_In_opt_ LPVOID lpInBuffer,
_In_ DWORD nInBufferSize,
_Out_opt_ LPVOID lpOutBuffer,
_In_ DWORD nOutBufferSize,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);

设置FSCTL_SET_SPARSE标记可以产生稀疏文件,以下代码是一个例子:

    hFile = CreateFile("tmp_file", GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, CREATE_ALWAYS,,NULL);
DWORD dwTemp;
DeviceIoControl(hFile,FSCTL_SET_SPARSE, NULL,,NULL,,&dwTemp,NULL); SetFilePointer(hFile, 0x100000, NULL, FILE_BEGIN);
WriteFile(hFile,"", , &nWritten, NULL);
SetEndOfFile(hFile);
CloseHandle(hFile);

通过GetFileInformationByHandle可以查看文件是否为稀疏文件:

BOOL WINAPI GetFileInformationByHandle(
_In_ HANDLE hFile,
_Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation
);

FSCTL_SET_SPARSE

lseek函数与文件空洞的更多相关文章

  1. Linux C ftruncate 函数清空文件注意事项(要使用 lseek 重置偏移量)

    转载:http://blog.csdn.net/a_ran/article/details/43562429 int truncate(const char *path, off_t length); ...

  2. lseek函数

    所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为 cfo.cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数.读写操作通常开始于 cfo,并 ...

  3. 《UNIX环境高级编程》笔记--read函数,write函数,lseek函数

    1.read函数 调用read函数从文件去读数据,函数定义如下: #include <unistd.h> ssize_t read(int filedes, void* buff, siz ...

  4. APUE学习笔记(2):lseek()练习与文件洞

    对于lseek函数早在大一的C语言课上就有接触,但是几乎没有使用过,只记得是和文件偏移操作相关的 看了APUE上的示例,又使用od工具查看了内容,果然很神奇,很新鲜 figure3.2.c [c] # ...

  5. 在系统中使用read函数读取文件内容

    read函数(读取文件) read函数可以读取文件.读取文件指从某一个已打开地文件中,读取一定数量地字符,然后将这些读取的字符放入某一个预存的缓冲区内,供以后使用. 使用格式如下: number = ...

  6. Unix系统编程()文件空洞

    如果程序的文件偏移量已然跨越了文件结尾,然后再执行IO操作,将会发生什么情况? read调用将会返回0,表示文件结尾.令人惊讶的是,write函数可以在文件结尾后的任意位置写入数据. 从文件结尾后到新 ...

  7. 第五篇:使用无缓冲IO函数读写文件

    前言 本文介绍使用无缓冲IO函数进行文件读写. 所谓的无缓冲是指该IO函数通过调用系统调用实现,其实系统调用内部的读写实现也是使用了缓冲技术的. 读写步骤 1. 打开文件 open 函数 2. 读写文 ...

  8. 使用无缓冲IO函数读写文件

    前言 本文介绍使用无缓冲IO函数进行文件读写. 所谓的无缓冲是指该IO函数通过调用系统调用实现,其实系统调用内部的读写实现也是使用了缓冲技术的. 读写步骤 1. 打开文件 open 函数 2. 读写文 ...

  9. zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法

    转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法: ze ...

随机推荐

  1. [svc][op]Ubuntu初始化安装-py用机器优化

    参考: centos7安装优化 关闭防火墙 ufw disable pip换源 yum install python-pip -y mkdir ~/.pip cat > pip.conf< ...

  2. C#二叉树简易实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  3. Books from Joe's blog

    Some books that I really enjoy(ed) It's been quite some time since I blogged about what I've been re ...

  4. angular学习笔记(十四)-$watch(1)

    本篇主要介绍$watch的基本概念: $watch是所有控制器的$scope中内置的方法: $scope.$watch(watchObj,watchCallback,ifDeep) watchObj: ...

  5. 山寨一个std::bind\boost::bind

    这里是最初始的版本,参考https://github.com/cplusplus-study/fork_stl/blob/master/include/bind.hpp 提供了最简洁的实现方式. 第一 ...

  6. 前端面试题 -- JS篇

    前端面试题 -- JS篇 类型 1.js中有哪些数据类型,并解释清楚原始数据类型和引用数据类型 js中共有null,undefined, string,number,boolean,object六种数 ...

  7. SQLAlchemy的“缓存”问题导致的BUG

    问题描述: 最近做项目,遇到一个问题,两个项目操作同一个数据库,其中A项目用的pymysql链接操作数据库,B项目用的sqlalchemy,当我请求B项目中的一个接口,会通知A项目操作数据库,然后返回 ...

  8. pairRDD中算子reduceByKeyLocally

    原型: def reduceByKeyLocally(func: (V, V) => V): Map[K, V] 该函数将RDD[K,V]中每个K对应的V值根据映射函数来运算,运算结果映射到一个 ...

  9. LeetCode: Rotate Image 解题报告

    Rotate ImageYou are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees ( ...

  10. jquery 替换原来的html内容

    1.replaceWith() 使用括号内的内容替换所选择的内容. $("#div").replaceWith("<div id="div2"& ...