我得到了1TB的稀疏文件,它实际上在Linux上存储了32MB的数据.
是否有可能"有效"地创建一个包来存储稀疏文件?应将程序包解压缩为另一台计算机上的1TB稀疏文件.理想情况下,"包"应该在32MB左右.
注意:可能的解决方案是使用'tar':https://wiki.archlinux.org/index.php/Sparse_file#Archiving_with_.60tar.27
但是,对于1TB稀疏文件,尽管tar球可能很小,但归档稀疏文件将花费很长时间.
编辑1
我测试了tar和gzip,结果如下(请注意,这个稀疏文件包含0字节的数据).
$ du -hs sparse-1
0 sparse-1
$ ls -lha sparse-1
-rw-rw-r-- 1 user1 user1 1.0T 2012-11-03 11:17 sparse-1
$ time tar cSf sparse-1.tar sparse-1
real 96m19.847s
user 22m3.314s
sys 52m32.272s
$ time gzip sparse-1
real 200m18.714s
user 164m33.835s
sys 10m39.971s
$ ls -lha sparse-1*
-rw-rw-r-- 1 user1 user1 1018M 2012-11-03 11:17 sparse-1.gz
-rw-rw-r-- 1 user1 user1 10K 2012-11-06 23:13 sparse-1.tar
Run Code Online (Sandbox Code Playgroud)
包含0字节数据的1TB文件sparse-1可以通过'tar'存档到10KB tar球或通过gzip压缩到~1GB文件.gzip占用tar时间的2倍左右.
从比较来看,'tar'似乎比gzip更好.
但是,对于包含0字节数据的稀疏文件,96分钟太长.
编辑2
rsync似乎完成复制文件的时间超过tar但小于gzip: …
什么是稀疏文件,为什么需要它?我唯一能得到的是它是一个非常大的文件,它是高效的(千兆字节).效率如何?
考虑一个稀疏文件,其中1s写入文件的一部分.
我想回收磁盘上这些1的实际空间,因为我不再需要稀疏文件的那部分.包含这些1的文件部分应该成为一个"洞",就像1s自己写的那样.
为此,我将该区域清除为0.这并没有收回磁盘上的块.
我如何实际制作稀疏文件,再次稀疏?
这个问题与此类似,但该问题没有被接受的答案.
考虑在库存Linux服务器上运行的以下事件序列:
$ cat /tmp/test.c
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char **argv) {
int fd;
char c[1024];
memset(c,argc==1,1024);
fd = open("test",O_CREAT|O_WRONLY,0777);
lseek(fd,10000,SEEK_SET);
write(fd,c,1024);
close(fd);
return 0;
}
$ gcc -o /tmp/test /tmp/test.c
$ /tmp/test
$ hexdump -C ./test
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002710 01 01 01 01 01 01 01 01 …Run Code Online (Sandbox Code Playgroud) 我正在测试一个稀疏文件.但我的测试代码效果不佳.
HANDLE h = CreateFileW(L"D:\\sparse.test",
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SPARSE_FILE,
0);
DWORD d = GetFileAttributes(L"D:\\sparse.test");
// The function returns 32(FILE_ATTRIBUTE_ARCHIVE).
// Where is FILE_ATTRIBUTE_SPARSE_FILE flag?
// How do I make a sparse file.
DWORD written;
WriteFile(h, "aaa", 3, &written, 0);
SetFilePointer(h, 2*1024*1024*1023, 0, FILE_BEGIN);
SetEndOfFile(h);
WriteFile(h, "bbb", 3, &written, 0);
Run Code Online (Sandbox Code Playgroud) 我在python中创建稀疏文件如下:
>>> f = open('testfile', 'ab')
>>> f.truncate(1024000)
>>> f.close()
Run Code Online (Sandbox Code Playgroud)
文件完成后,占用0个磁盘空间,但其inode大小设置为我的截断值(1000K):
igor47@piglet:~/test$ ls -lh testfile
-rw-r--r-- 1 igor47 igor47 1000K 2010-07-09 04:02 testfile
igor47@piglet:~/test$ du -hs testfile
0 testfile
Run Code Online (Sandbox Code Playgroud)
如何在python中获取文件的实际空间使用量(分配大小)?该stat调用返回文件的表观大小,我不知道如何获得除了读取整个文件之外的其他实际用法(它可能会变得非常大)
>>> os.stat('testfile').st_size
1024000
Run Code Online (Sandbox Code Playgroud) 如果我有一个包含许多零的大文件,我怎样才能有效地使它成为稀疏文件?
唯一的可能是读取整个文件(包括可能存储稀疏的所有零)并使用seek跳过零区域将其重写为新文件?
或者是否有可能在现有文件中进行此操作(例如File.setSparse(long start,long end))?
我正在寻找Java或某些Linux命令的解决方案,Filesystem将是ext3或类似的.
如果你用这个运行dd:
dd if=/dev/zero of=sparsefile bs=1 count=0 seek=1048576
Run Code Online (Sandbox Code Playgroud)
您似乎获得了一个完全未分配的稀疏文件(这是ext4)
smark@we:/sp$ ls -ls sparsefile
0 -rw-rw-r-- 1 smark smark 1048576 Nov 24 16:19 sparsefile
Run Code Online (Sandbox Code Playgroud)
fibmap同意:
smark@we:/sp$ sudo hdparm --fibmap sparsefile
sparsefile:
filesystem blocksize 4096, begins at LBA 2048; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
Run Code Online (Sandbox Code Playgroud)
无需深入了解dd的来源,我正试图弄清楚如何在C中做到这一点.
我试过fseeking和写零字节,但它没有做任何事情.不知道还有什么可以尝试,我想在我追捕dd的内脏之前有人可能知道.
编辑:包括我的例子......
FILE *f = fopen("/sp/sparse2", "wb");
fseek(f, 1048576, SEEK_CUR);
fwrite("x", 1, 0, f);
fclose(f);
Run Code Online (Sandbox Code Playgroud) 给定文件描述符或文件名,如何知道是否可以写入任意位置而无需等待介入部分在磁盘上显式清零?
如果我创建一个文件,用于lseek(2)跳到(空)文件中的较高位置,然后在其中写入一些有价值的信息,那么我会在Unix系统上创建一个稀疏文件(可能取决于我使用的文件系统,但是假设我m使用典型的Unix文件系统(例如ext4或类似文件),就是这种情况。
如果然后我lseek(2)在文件中甚至更高的位置上写一些东西,我最终会得到一个稀疏文件,该文件的中间位置包含有价值的信息,并被大量稀疏文件包围。我想在文件中找到这些有价值的信息,而不必完全阅读它。
例:
$ python
f = open('sparse', 'w')
f.seek((1<<40) + 42)
f.write('foo')
f.seek((1<<40) * 2)
f.write('\0')
f.close()
Run Code Online (Sandbox Code Playgroud)
这将创建一个仅使用8k磁盘空间的2TB文件:
$ du -h sparse
8.0K sparse
Run Code Online (Sandbox Code Playgroud)
中间的某处(1TB + 42字节)是有价值的信息(foo)。
我cat sparse当然可以找到它,但是它将读取完整的文件并输出大量的零字节。我尝试使用较小的尺寸,发现此方法大约需要3个小时才能在计算机上打印三个字符。
问题是:
有没有一种方法可以找到存储在稀疏文件中的信息,而无需同时读取所有空块?我可以使用标准的Unix方法以某种方式找出稀疏文件中的空块吗?
我想将文件从一个地方复制到另一个地方,问题是我处理了很多稀疏文件.
是否有任何(简单)方法复制稀疏文件而不会在目的地变得庞大?
我的基本代码:
out, err := os.Create(bricks[0] + "/" + fileName)
in, err := os.Open(event.Name)
io.Copy(out, in)
Run Code Online (Sandbox Code Playgroud) 我打算在log或diskqueue这样的系统中使用fdatasync.第一件事是在文件系统中创建一个带有"000000 ..."的10MB文件,如ext4.但我不知道如何正确地做到这一点.
我有一个python3使用numpy.memmap数组操作的脚本.它将数组写入新生成的临时文件,该文件位于/tmp:
import numpy, tempfile
size = 2 ** 37 * 10
tmp = tempfile.NamedTemporaryFile('w+')
array = numpy.memmap(tmp.name, dtype = 'i8', mode = 'w+', shape = size)
array[0] = 666
array[size-1] = 777
del array
array2 = numpy.memmap(tmp.name, dtype = 'i8', mode = 'r+', shape = size)
print('File: {}. Array size: {}. First cell value: {}. Last cell value: {}'.\
format(tmp.name, len(array2), array2[0], array2[size-1]))
while True:
pass
Run Code Online (Sandbox Code Playgroud)
硬盘的大小只有250G.尽管如此,它可以以某种方式生成10T大文件/tmp,并且相应的数组似乎仍然可以访问.脚本的输出如下:
File: /tmp/tmptjfwy8nr. Array size: 1374389534720. …Run Code Online (Sandbox Code Playgroud)