Я тестировал код из APUE, в главе 14 (Advanced I/O) из файла карты памяти, то fstat()
всегда возвращают fdin
«s st_size
как ноль, и я попытался stat()
вместо этого, а также получить тот же результат , Я перечисляю код ниже (я удалил apue.h зависимостей):Почему stat и fstat возвращают st_size == 0?
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define COPYINCR (1024*1024*1024) /* 1GB */
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("usage: %s <fromfile> <tofile>", argv[0]);
exit(1);
}
int fdin, fdout;
if ((fdin = open(argv[1], O_RDONLY)) < 0) {
printf("can not open %s for reading", argv[1]);
exit(1);
}
if ((fdout = open(argv[2] /* typo fix */, O_RDONLY | O_CREAT | O_TRUNC)) < 0) {
printf("can not open %s for writing", argv[2]);
exit(1);
}
struct stat sbuf;
if (fstat(fdin, &sbuf) < 0) { /* need size fo input file */
printf("fstat error");
exit(1);
}
// always zero, and cause truncate error (parameter error)
printf("input_file size: %lld\n", (long long)sbuf.st_size);
if (ftruncate(fdout, sbuf.st_size) < 0) { /* set output file size */
printf("ftruncate error");
exit(1);
}
void *src, *dst;
off_t fsz = 0;
size_t copysz;
while (fsz < sbuf.st_size) {
if (sbuf.st_size - fsz > COPYINCR)
copysz = COPYINCR;
else
copysz = sbuf.st_size - fsz;
if (MAP_FAILED == (src = mmap(0, copysz, PROT_READ,
MAP_SHARED, fdin, fsz))) {
printf("mmap error for input\n");
exit(1);
}
if (MAP_FAILED == (dst = mmap(0, copysz,
PROT_READ | PROT_WRITE,
MAP_SHARED, fdout, fsz))) {
printf("mmap error for output\n");
exit(1);
}
memcpy(dst, src, copysz);
munmap(src, copysz);
munmap(dst, copysz);
fsz += copysz;
}
return 0;
}
А потом я попробовал Python os.stat
, он также получить нулевой результат, почему это произошло? Я пробовал их и получил тот же результат на Mac OS (ядро Darwin 13.4) и Ubuntu (ядро 3.13).
UPDATE: О, там была ошибка опечатка, я должен обратиться к fdout
к argv[2]
и O_TRUNC
флаг, конечно, сделать fdin
к нулю. Должен ли я закрыть или удалить этот вопрос?
Причина Питона os.stat()
также возвращает (stat.st_size == 0)
, что я прошел же тестовый файл (argv[1]
), чтобы проверить, и файл был ранее усекается до нуля (я не проверить его размер с помощью ls -lh
перед переходом к os.stat()
), и, конечно, os.stat()
return zero.
Не задавайте вопросов, прежде чем ложиться спать или спешить.
Когда вы открываете 'fdout',' O_TRUNC' обрезает его. Поскольку и 'fdout', и' fdin' относятся к одному и тому же имени файла ('argv [1]'), конечно, размер будет равен нулю - вы просто усекали его. –
+1 Одна из официальных целей stackoverflow - [решение проблемы резиновых уток] (http://blog.codinghorror.com/rubber-duck-problem-solving/), поэтому не стесняйтесь - вы сделали правильно, отлично вопрос. –
Молодцы. Вы можете ответить на свой вопрос. – alk