Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите разобраться с буферизацией и чтением файл 
:(
    Опции темы
tumanovalex
  Дата 17.8.2008, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 3.1.2005

Репутация: нет
Всего: нет



В параметрах программы я задаю, будет ли использовать буферизация (bufyes=0 - нет буферизациии) и размер буфера (bufsize) при чтении файла. У Шилда в справочнике прочел, что если функции setvbuf задать нулевой размер буфера, то она выделит сама какой-то размер буфера. Поэтому кодирую так:
Код

char *p, *buf;
  if(parini.bufyes==0) { // если в параметрах указано, что буферизация отсутствует
    p = malloc(256); // у Шилда в справочнике написано, что если параметр p (буфер) нулевой, то setvbuf выделяет собственный буфер. 
    if(setvbuf(pfile, p, _IONBF, 256)!=0) { // отключаю буферизацию _IONBF 
      printf("Can't make bufer with size %l\n", 0);
      exit(1);
    } // if setvbuf!=0 
  buf = malloc(parini.bufsize); //выделяю буфер для чтения 
  }  //if
  else {
    buf = malloc(parini.bufsize);
    if(setvbuf(pfile, buf, _IOFBF, parini.bufsize)!=0) { // если буферизация есть, то полностью использую заданный размер буфера buf
      printf("Can't make bufer with size %l\n", parini.bufsize);
      exit(1);
    } // if(setvbuf!=0 
  } //else

Далее я читаю файл и проверяю количество считанных байтов для выхода в случае ошибки или конца файла 
Код

  nbyte = parini.bufsize;
  i = 0;
  while(0x1B != _getch()) { // Пока не нажата клавиша "Esc"
    i++;
    if(fread(buf, 1, nbyte, pfile)!=nbyte) {
      printf("Error during read cycle = %l", i);
      exit(1);
    } // if(fread
   }
  fclose(pfile); 

Программа зависает и выходит только по нажатию клавиши Esc. В связи с непониманием основополагающих вопросов ввода-вывода первыми идут "теоретические" вопросы, а потом вопрос № 6 о проблеме в программе:
1. setvbuf по _IONBF отключает буферизацию ввода-вывода. Это значит, что операционная система (ОС) не выделяет буферы при чтение данных из файла?
2. Когда я при _IONBF делаю буфер нужного мне размера для операции чтения, я выделяю буфер в ОЗУ и тем самым операцию чтению буферизую? Т.е. я самостоятельно управляю буферизацией и в этом мне ОС не мешает? 
3. Если я использую _IOFBF, то ОС выделяет буфер таким, как я установил в setvbuf и плюс к этому я еще создаю свой буфер для операции чтения? А какое должно быть оптимальное соотношение этих буферов, чтобы производительность ввода-вывода была максимальна?
4. Если я вообще не использую setvbuf, то ОС создаст буфер для ввода-вывода самостоятельно? А какого размера тогда он будет и как это можно определить? 
5. После компиляции в Windows в исполняемом файле будут присутствовать функции API Win32 (в моем случае CreateFile и ReadFile), а в Linux - API Linux? Какими средствами можно узнать, какие API-функции будут вызываться исполняемым файлом?
6. Почему программа у меня не завершается? Ведь достигнув конец файла, функция fread должна вернуть значение, не совпадающее с nbyte.
Помогите, пожалуйста, разобраться! 
PM MAIL   Вверх
bsa
Дата 17.8.2008, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



1. да
2. _IONBF полностью отключает стандартную буферизацию потока и неважно, сколько памяти ты выделил.
3. память выделяется в этом случае только если ты вместо указателя на буфер передал NULL, иначе используется тот буфер, который ты предоставил. Чем больше буфера, тем выше скорость, но тем выше вероятность потери данных при сбое (буфера на запишутся на диск) и меньше памяти под данные.
4. Вот цитата из документации:
Цитата
                                                                                            Normally all files are block
       buffered.  When the first I/O operation occurs on a file, malloc(3) is called, and a buffer is  obtained.   If  a
       stream  refers  to a terminal (as stdout normally does) it is line buffered.  The standard error stream stderr is
       always unbuffered by default.
В переводе начало звучит так: "Обычно все файлы имеют блочную буферизацию..."
5. Как сделать в Windows, я не знаю. Под линукс тебе могут помочь программы strace и ldd
6. сделай в цикле отладочный вывод (printf понатыкай) или пройдись отладчиком.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0627 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.