Note que, embora a chamada do sistema seja chamada de truncada, na verdade, é melhor interpretá-la como dizendo "Fazer com que o meu arquivo relate esse número de bytes em tamanho". De acordo com a manpage do sistema:
The truncate() and ftruncate() functions cause the regular file named by path or referenced by fd to be truncated to a size of precisely length bytes.
If the file previously was larger than this size, the extra data is lost. If the file previously was shorter, it is extended, and the extended part reads as null bytes ('
').So my questions is, if my process has an opened file in pos 1000 and i did truncate -s0 filename, if the truncate works, what happening in the next process write?
Assim, pode-se truncar um arquivo e torná-lo maior, em vez de menor.
%bl0ck_qu0te%- Você truncou. O tamanho do arquivo nesse estágio é de 0 bytes. O deslocamento é de 1000.
- A gravação na posição 1001 ocorre.
- O tamanho do arquivo é de 1002 bytes. Bytes 0-1000 contêm '\ 0' (nulo). Os bytes 1001+ contêm dados gravados.
Quando você grava em um arquivo de uma posição maior que o próprio arquivo, os dados entre o final do arquivo e a nova gravação se tornam bytes nulos e os dados do arquivo entre esses dois pontos são referidos como esparsos .
De fato, você pode fazer o seguinte e produzir o mesmo efeito.
import os, sys
f = open('data.txt','w')
f.seek(1048576)
f.write('a')
f.flush()
f.close()
Você também mencionou que a abertura no modo de anexação evita esse comportamento. Isso é verdade porque você está instruindo o kernel nesse caso para "gravar no final real do arquivo toda vez". Se você truncar, o final do arquivo será alterado. Ao acrescentar, você não pode reposicionar seu ponteiro de arquivo.
Aqui está um exemplo de programa que demonstra o que acontece com o arquivo, os deslocamentos e os dados em um arquivo que foi truncado.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <err.h>
#define FPATH "/tmp/data.txt"
#define FSIZE 65536
int main() {
int a,b;
char buf[FSIZE];
char byte;
struct stat st;
memset(buf, 'A', FSIZE);
a = open(FPATH, O_WRONLY|O_CREAT);
b = open(FPATH, O_RDONLY);
if (a < 0 || b < 0)
errx(EXIT_FAILURE, "Could not open file");
printf("Writing %d * 'A' into file\n", FSIZE);
/* Write some bytes */
if(write(a, buf, FSIZE) != FSIZE)
errx(EXIT_FAILURE, "Couldn't write complete size out");
/* Seek to a new position in the file */
lseek(b, FSIZE/2, SEEK_SET);
printf("Current position of handle 'a': %d\n", lseek(a, 0, SEEK_CUR));
printf("Current position of handle 'b': %d\n", lseek(b, 0, SEEK_CUR));
stat(FPATH, &st);
printf("Reported size on filesystem of %s: %d\n", FPATH, st.st_size);
/* OK -- now, read the byte at the position */
if (read(b, &byte, 1) < 0)
err(EXIT_FAILURE, "Could not read file");
printf("Character at current position of handle 'b': '%c'\n", byte);
/* Truncate the file in the 'a' handle */
printf("Performing truncate...\n");
if (ftruncate(a, 0) < 0)
err(EXIT_FAILURE, "Cannot truncate file");
printf("Current position of handle 'a': %d\n", lseek(a, 0, SEEK_CUR));
printf("Current position of handle 'b': %d\n", lseek(b, 0, SEEK_CUR));
stat(FPATH, &st);
printf("Reported size on filesystem of %s: %d\n", FPATH, st.st_size);
printf("Writing one byte via handle 'a'\n");
if (write(a, buf, 1) < 0)
err(EXIT_FAILURE, "Cannot perform second write");
printf("Current position of handle 'a': %d\n", lseek(a, 0, SEEK_CUR));
printf("Current position of handle 'b': %d\n", lseek(b, 0, SEEK_CUR));
stat(FPATH, &st);
printf("Reported size on filesystem of %s: %d\n", FPATH, st.st_size);
if (read(b, &byte, 1) < 0)
err(EXIT_FAILURE, "Could not read file");
printf("Character at current position of handle 'b': '%c'\n", byte);
close(a);
close(b);
exit(0);
}
Isso resulta na seguinte saída;
Writing 65536 * 'A' into file
Current position of handle 'a': 65536
Current position of handle 'b': 32768
Reported size on filesystem of /tmp/data.txt: 65536
Character at current position of handle 'b': 'A'
Performing truncate...
Current position of handle 'a': 65536
Current position of handle 'b': 32769
Reported size on filesystem of /tmp/data.txt: 0
Writing one byte via handle 'a'
Current position of handle 'a': 65537
Current position of handle 'b': 32769
Reported size on filesystem of /tmp/data.txt: 65537
Character at current position of handle 'b': ''