Чтение файла-устройства

197
12 апреля 2017, 15:46

Возникла задача прочитать файл-устройство. Делаю так:

#include <iostream>
#include <fstream>
#include <vector>
int main()
{
    std::fstream filestream;
    filestream.rdbuf()->pubsetbuf(0, 0);
    filestream.open("/dev/sdc1",  std::ios_base::binary | std::ios_base::in | std::ios_base::out);
    std::vector<char> vec(512);
    unsigned short size;
    while ((size = filestream.readsome(&vec[0], vec.size())))
    {
        // какие-то действия
    }
    filestream.close();
    return 0;
}

Однако, этот код работает только при чтении обычных файлов. Когда я пытаюсь прочитать таким образом файл-устройство, то readsome возвращает 0.

При этом, используя метод read, я могу читать оба типа файлов. Однако этот метод не работает желаемым образом, если размер буфера указан больше, чем число прочитанных байт (я так понял, что возвращает null).

Как правильно реализовать задуманное?

==================== UPDATE ====================

Рабочий код на Си.

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <error.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    const char key = 0xFF;
    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return EXIT_FAILURE;
    }
    int fd = open(argv[1], O_RDWR);
    if (fd < 0)
    {
        fprintf(stderr, "Error occurs while openning %s: %s\n", argv[1], strerror(errno));
        return EXIT_FAILURE;
    }
    char buffer[512];
    unsigned short n;
    while ((n = read(fd, buffer, 512)) > 0)
    {
        for (unsigned short i = 0; i < n; ++i)
            buffer[i] ^= key;
        lseek(fd, -n, SEEK_CUR);
        write(fd, buffer, n);
    }
    close(fd);
    return EXIT_SUCCESS;
}
Answer 1

используйте метод basic_istream& std::basic_istream::get( char_type* s, std::streamsize count );

Answer 2

На самом деле, вопрос совсем не прост! Вспоминаем, что:

  1. Файлы каталога /dev - псевдофайлы, обеспечивающие доступ к драйверу
  2. Есть два основных типа драйверов: символьные и блочные.

Когда загружается драйвер последовательного (символьного) устройства, то он регистрирует в ядре список операций, которые этот драйвер может выполнять. Среди этих операций может быть операция ЧТЕНИЯ (Поле .read в списке операций драйвера).

Для блочных устройств это не так. Вот цитата из библии "Драйверы устройств Linux", Третья редакция (Jonathan Corbet):

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

Проще говоря - когда вы пытаетесь читать с УСТРОЙСТВА /dev/sda, Вы получите нечто, не имеющие никакого отношения к содержимому диска / флэшки.

Ну а то, что ваша программа на чистом С, якобы, работала - у меня вызывает некоторые сомнения. Что значит РАБОТАЛА? Вы какими средствами смотрели нулевой сектор нулевой дорожки нулевого цилиндра ? Сравнивали с тем, что "видит" Ваша программа ? Сдаётся, мне что Вы просто НЕ проверяли код завершения, возвращаемый read(...).

READ ALSO
Программно изменить реестр через WinApi

Программно изменить реестр через WinApi

Здравствуйте! Скажу сразу, это проблемная для меня темаВ ветви HKEY_CURRENT_USER нужно изменить значение ColorizationGlassReflectionIntensity, находящееся в Software\\Microsoft\\Windows\\DWM

292
Можно ли как-то изменить степень размытия фона эффекта AeroGlass через DWM API?

Можно ли как-то изменить степень размытия фона эффекта AeroGlass через DWM API?

Можно ли как-то изменить степень размытия фона эффекта AeroGlass через DWM API?

283
Нарушение прав доступа при чтении

Нарушение прав доступа при чтении

Помогите, я не могу найти ошибку уже очень давно!

192
Как узнать есть ли петля в графе?

Как узнать есть ли петля в графе?

Не знаю как решить ? Можете сказать как можно решить эту задачу ?

623