c программирование содержимого read () и write () в файл - PullRequest
0 голосов
/ 10 декабря 2010

Пользователь должен ввести некоторые имена файлов в командной строке, и программа будет читать каждое имя файла из массива argv[]. Я должен выполнить проверку ошибок и т. Д.

Я хочу прочитать каждое имя файла. Например, если argv [2] равно «myfile.txt», программа должна прочитать содержимое «myfile.txt» и сохранить значение в char buffer[BUFSIZ], а затем записать содержимое buffer в другой файл.

Однако перед тем, как содержимое будет написано, программа должна также написать имя файла и его размер. Такой, что файл может быть легко извлечен позже. Немного похоже на функцию tar.

Файл, в который я записываю содержимое buffer, в зависимости от количества файлов, добавленных пользователем, должен иметь вид строки:

myfile.txt256Thisisfilecontentmyfile2.txt156Thisisfile2content..............

Мой вопрос

1) Как записать значение argv[2] в файл с помощью оператора write(), так как возникают проблемы при записи массива char, что я должен поместить в (sizeof (?)) Внутри write() , см. ниже, поскольку я не знаю длину имени файла, введенного пользователем.

2) Должен ли я использовать '&', чтобы записать целое значение в файл после имени, например записать 4 байта после имени файла для размера файла

Вот код, который я написал,

char buffer[BUFSIZ];
int numfiles=5; //say this is no of files user entered at command
open(file.....

lseek(fdout, 0, SEEK_SET); //start begging of file and move along each file some for loop

for(i=0-; ......
//for each file write filename,filesize,data....filename,filesize,data......
int bytesread=read(argv[i],buffer,sizeof(buffer));
write(outputfile, argv[i], sizeof(argv)); //write filename size of enough to store value of filename
write(outputfile, &bytesread, sizeof(bytesread));
write(outputfile, buffer, sizeof(buffer));

Но код работает не так, как я ожидал.

Есть предложения?

Ответы [ 4 ]

2 голосов
/ 10 декабря 2010

Поскольку argv состоит из массивов с нулевым символом в конце, длина, которую вы можете написать, равна strlen(argv[2])+1 для записи как аргумента, так и нулевого терминатора:

size_t sz = strlen (argv[2]);
write (fd, argv[2], sz + 1);

В качестве альтернативы, если вы хотите, чтобы длина следовала послесимволов, вы можете написать сам size_t, возвращаемый из strlen, за которым следует такое количество символов.

size_t sz = strlen (argv[2]);
write (fd, &sz, sizeof (size_t));
write (fd, argv[2], sz);

Возможно, вам также потребуется записать длину файла, чтобы вы могли найтиследующий файл при чтении обратно.

0 голосов
/ 10 декабря 2010

спасибо за ответы, ребята,

Я решил не использовать структуру (size_t), а просто назначил (int) и (char) типы, так что я знаю точное значение байтов для чтения ().то есть я знаю, что начинаю с начала файла и читаю 4 байта (целых), чтобы получить значение длины имени файла, которое я использую в качестве размера при следующем чтении ()

Итак, когда я пишу (копирую файл точно содно и то же имя) пользователь ввел файл в выходной файл (скопированный файл). Я записал его в длинную строку, без пробелов, очевидно, просто для того, чтобы сделать его читаемым здесь,

filenamesize filename*

Поэтому, когда я приступил к чтению этих данных, я начинаю с начала файла, используя lseek (), и я знаю, что первые 4 байта (int) - это длина имени файла, поэтому я помещаю это в значение int namelen, используя функцию чтения.,

Моя проблема в том, что я хочу использовать это значение для размера имени файла (первые 4 байта), чтобы объявить мой массив для хранения имени файла с правильной длиной.Как поместить этот массив в read (), чтобы значение read сохранялось внутри указанного массива char, см. Ниже, пожалуйста,

int namelen; //value read from first 4 bytes of file lenght of filename to go in nxt read()
char filename[namelen]; 
read(fd, filename[namelen], namelen);//filename should have 'myfile.txt' if user entered that filename

Итак, мой вопрос: как только я прочитаю первые 4 байта из файла, что даст мне длинуимя файла хранится в namelen, затем я хочу прочитать namelen количество байтов, чтобы дать мне имя файла исходного файла, чтобы я мог создать скопированный файл в каталоге?

Спасибо

0 голосов
/ 10 декабря 2010

Похоже, вам лучше всего использовать двоичный формат.В вашем примере файл с именем myfile.txt имеет длину содержимого 256, или myfile.txt2 с длиной содержимого 56, или myfile.txt25 с длиной содержимого 6?Нет никакого способа различить конец имени файла и начало поля длины содержимого.Точно так же нет никакого способа различить конец длины контента и начало контента.Если вы должны использовать текстовый формат, поля фиксированной ширины помогут в этом.Т.е. 32 символа имени файла сопровождаются 6 цифрами длины содержимого.Но двоичный формат более эффективен.

Вы получаете длину имени файла, используя strlen (), не используйте sizeof(argv), так как вы получите совершенно неверный результат.sizeof(argv[i]) также даст неверный результат.

Итак, запишите 4 байта длины имени файла, затем имя файла, затем 4 байта длины содержимого и затем содержимое.

Если вы хотите, чтобы формат был переносимым, вам необходимо знать о проблемах порядка следования байтов.

Наконец, если файл не все умещается в вашем буфере, значит, вы заполнены.Вам нужно получить размер файла, который вы читаете, чтобы сначала записать его в выходной файл, а затем убедиться, что вы прочитали это количество байтов из первого файла во второй файл.Для этого есть разные техники.

0 голосов
/ 10 декабря 2010

1., Вы можете написать строку следующим образом:

size_t size = strlen(string);
write(fd, string, size);

Однако, в большинстве случаев это не так просто: вам понадобится размер строки, чтобы вы знали, скольковам нужно прочитать.Таким образом, вы должны написать размер строки тоже.

2., Целое число можно записать следующим образом:

write(fd, &integer, sizeof(integer));

Это просто, но если вы планируете использовать файл на разныхархитектуры, вам также придется иметь дело с порядком байтов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...