2015-11-24 12 views
6

Se si esegue dd con questo:Come si crea un file sparse completamente vuoto su Linux?

dd if=/dev/zero of=sparsefile bs=1 count=0 seek=1048576 

appari per ottenere un file sparse completamente non allocato (questo è ext4)

[email protected]:/sp$ ls -ls sparsefile 
0 -rw-rw-r-- 1 smark smark 1048576 Nov 24 16:19 sparsefile 

fibmap è d'accordo:

[email protected]:/sp$ sudo hdparm --fibmap sparsefile 
sparsefile: 
filesystem blocksize 4096, begins at LBA 2048; assuming 512 byte sectors. 
byte_offset begin_LBA end_LBA sectors 

Senza dover scavare attraverso la fonte di dd, sto cercando di capire come farlo in C.

Ho provato a guardare e scrivere zero byte, ma non ha fatto nulla. Non so cos'altro provare, ho pensato che qualcuno potrebbe saperlo prima di dare la caccia alle interiora di dd.

EDIT: tra cui il mio esempio ...

FILE *f = fopen("/sp/sparse2", "wb"); 
fseek(f, 1048576, SEEK_CUR); 
fwrite("x", 1, 0, f); 
fclose(f); 
+1

'dd' è open source. prendi la fonte e guarda attraverso di essa ... –

+0

devi aver perso la parte su "senza dover scavare attraverso la fonte di dd". Ho pensato che qualcuno potrebbe solo sapere. – stu

+0

Forse non capisco la domanda ma stai cercando 'touch '? –

risposta

6

Quando si scrive in un file utilizzando write o varie routine di libreria che alla fine chiama write, c'è un file di puntatore compensare associato al descrittore di file che determina dove nel file andranno i byte. Normalmente viene posizionato alla fine dei dati elaborati dalla chiamata più recente a read o write. Ma puoi usare lseek per posizionare il puntatore ovunque all'interno del file e anche oltre la fine attuale del file. Quando si scrivono dati in un punto oltre l'EOF corrente, l'area che è stata saltata è concettualmente piena di zeri. Molti sistemi ottimizzeranno le cose in modo che tutti i blocchi dell'intero filesystem in quell'area saltata semplicemente non siano allocati, producendo un file sparse. I tentativi di leggere tali blocchi avranno esito positivo, restituendo zero.

La scrittura di aree di dimensioni di blocco piene di zeri su un file generalmente non produrrà un file sparse, sebbene per alcuni file system sia possibile farlo.

Un altro modo per produrre un file sparse, utilizzato da GNU dd, è chiamare ftruncate. Il documentation dice questo:

La funzione ftruncate() fa sì che il file regolare a cui fa riferimento fildes avere una dimensione di byte di lunghezza.

Se il file in precedenza era maggiore della lunghezza, i dati aggiuntivi vengono eliminati. Se in precedenza era più corto della lunghezza, non è specificato se il file è stato modificato o se le sue dimensioni sono aumentate. Se il file è esteso, l'area estesa viene visualizzata come se fosse riempita a zero.

Il supporto per i file sparse è specifico per il filesystem, anche se praticamente tutti i filesystem locali progettati per UNIX li supportano.

+0

Mi hai appena battuto esso! –

+0

zfs, a proposito, scrivendo blocchi di zeri contigui su un file (se uno schema di compressione è attivo) fondamentalmente perforerà quell'area in sparsità. – stu

+0

@stu Grazie per quello - speravo che le persone con esperienza in vari tipi di filesystem commentassero. Aggiungerò le informazioni aggiuntive alla mia risposta dopo alcuni giorni. –

3

Questa è complementare alla risposta da @MarkPlotnick, è un semplice esempio di implementazione della funzione che avete richiesto utilizzando ftruncate():

#include <unistd.h> 
#include <fcntl.h> 

#include <sys/stat.h> 

int 
main(void) 
{ 
    int file; 
    int mode; 

    mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 
    file = open("sparsefile", O_WRONLY | O_CREAT, mode); 
    if (file == -1) 
     return -1; 
    ftruncate(file, 0x100000); 
    close(file); 

    return 0; 
} 
+0

L'uso di 'fchmod()' qui non è raccomandato, poiché ignora 'umask'. La modalità dovrebbe essere passata a 'open()'. –

+0

Ecco, l'ho risolto. 'mode' è il terzo parametro di' open() '. –

+0

Grazie per aver pubblicato un esempio: aggiungi la riga di comando di analisi per nome file e dimensioni e sarebbe un'utilità utile. – ChuckCottrill

Problemi correlati