Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/32: Рейтинг темы: голосов - 32, средняя оценка - 4.69
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252

Сериализация и десериализация vector'а int'ов

05.03.2011, 16:26. Показов 6583. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имею вектор:
C++
1
std::vector<int> mig
Нужно очень быстро сохранить его в файл, а потом восстановить из файла, пользуясь тем фактом, что это вектор int'ов. Т.е. не содержет никаких структур и указателей на объекты вне самого вектора. Т.к. вектор находится в едином цельном куске памяти, то задача сводится к простому копированию этого участка памяти в файл. И потом обратно копирование всего файла в память.
Помогите пожалуйста реализовать
Спасибо
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.03.2011, 16:26
Ответы с готовыми решениями:

Сериализация и десериализация структуры
Есть структура с полями string , int. Вся информация пишется в файл.txt, мне нужно сделать сериализацию и десериализацию этого файла. ...

Сериализация и десериализация дерева
Здравствуйте. Стоит задача разработать консольное приложение для сериализации и десериализации дерева, в узлах которого могут храниться...

Сериализация и десериализация двусвязного списка
Всем доброго времени суток! Ребят помогите реализовать функции сериализации и десериализации двусвязного списка. Заранее спасибо

15
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
05.03.2011, 16:33
Union, Я бы просто считал вектор в файл - считал вектор из файла... Не вижу резона делать чего-либо другого...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <vector>
#include <fstream>
#include <algorithm>
#include <iostream>
#include <string>
 
int main()
{
    std::string f_name;
    std::cout<<"Enter file_name\n";
    std::cin>>f_name;
    std::cout<<"Enter elements of vector. / for end\n";
    std::vector<int> vc((std::istream_iterator<int>(std::cin)), std::istream_iterator<int>());
    std::ofstream ofs(f_name.c_str());
    //Здесь должна бы быть проверка на открытие
    std::copy(vc.begin(), vc.end(), std::ostream_iterator<int>(ofs, "\n"));
    vc.clear();
    ofs.close();
    std::ifstream ifs(f_name.c_str());
    //И тут проверка
    std::cin.clear();
    std::cin.get();
    std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(), std::back_inserter(vc));
    std::copy(vc.begin(), vc.end(), std::ostream_iterator<int>(std::cout, "\n"));
    return 0;
}
1
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 17:23  [ТС]
Посмотрел данный метод, вектор записывается в файл поэлементно через разделитель \n + каждый элемент конвертируется из int в string. А можно ли как-нибудь записывать в бинарном виде? Нужна максимальная производительность, в приложении постоянно копируются вектора по 500-900 тыс элементов. М.б.можно как-то через memcpy сразу по нескольку элементов копировать?
Спасибо.

Добавлено через 27 минут
Можно ли записывать Int'ы без конвертации в строки? Int = 4 байта - записывать 4 байта и потом считывать по 4 байта. Тогда разделитель \n не нужен. Каждые 4 байта соответствуют одному элементу в векторе.
0
 Аватар для insolent
829 / 353 / 64
Регистрация: 30.01.2009
Сообщений: 1,204
05.03.2011, 18:12
Union, открывай файл для бинарной записи.
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:02  [ТС]
Это смао собой Меня интересует реализация алгоритма вцелом. Т.е. не только как записать, но и как потом восстановить. В приведенном примере восстанавливается через разделитель \n. А так надо будет забирать по 4 байта.

Добавлено через 46 минут
C++
1
std::ofstream ofs("2.dat", std::ios::binary);
Вот открыл для бинарной записи.
C++
1
std::copy(vc.begin(), vc.end(), std::ostream_iterator<int>(ofs, "\n"));
всёравно переводит int в строку и записывает через разделитель.
Впринципе разделитель я молгу убрать, но как заставить std::copy записывать int как int, без конвертации?
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
05.03.2011, 19:18
я не силен в данной теме, но соображения
1) если это винда, то с помощью CreateFileMapping спроецировать файл в память с заданием размера
2) первым элементом записать int'ом размер вектора
3) с помощью memcpy записать весь вектор в духе memcpy( base, &v.front(), v.size() * sizeof(int) );

обратные действия понятны
1) открыть также файл для чтения
2) прочитать размер сделать v.resize( .. )
3) с помощью memcpy ( &v.front(), base, v.size() * sizeof(int) )

под линь тоже маппинг делают, но тут уж не просвещен
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:26  [ТС]
1) К сожалению это linux (Ubunta)
2) Размер записывать вовсе необязательно, я могу его сохранить отдельно, в базе. В общем вся задача сводится к банальному копированию участка памяти.
3) Я искал возможность через memcpy прямиком скопировать вектор, т.к. при данных условиях по быстродействию это решение было бы оптимальным, а поэлементное копирование, да ещё и спреобразованием - расточительство.
Пока про memcpy ничего не нашёл, жду, может кто здесь подскажет.
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
05.03.2011, 19:31
http://linux.die.net/man/2/mmap
http://www.cplusplus.com/refer... ng/memcpy/
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:35  [ТС]
Я в приложении часто использую memcpy с char'ами, но не имею никакого представления насчёт вектора. Мои знания насчёт вектора и stl вообще чисто поверхностные - это принцип работы, что такое итераторы и т.д. В общем я не знаю как применить memcpy в этой задаче...
0
 Аватар для igorrr37
2893 / 2040 / 992
Регистрация: 21.12.2010
Сообщений: 3,790
Записей в блоге: 9
05.03.2011, 19:37
читает и пишет блок памяти вроде как
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <vector>
#include <fstream>
#include <iostream>
 
int main(){
    std::vector<int> v={1,2,3,4,5,6}, res(10);
    std::ofstream ofs("1.dat", std::ios::binary);
    ofs.write(reinterpret_cast<char*>(&v[0]), v.size()*4);
    ofs.close();
    std::ifstream ifs("1.dat", std::ios::binary);
    if(!ifs){std::cerr<<"File not found"; return 1;}
    ifs.read(reinterpret_cast<char*>(&res[0]), res.size()*4);
    for(int i=0; i<res.size(); i++){
        std::cout<<res[i]<<"  ";
    }
    ifs.close();
}
1
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:46  [ТС]
igorrr37 спасибо за пример, но опять же лишние операции используются...
Вот я нашел темы про копирование вектора через memcpy:
std::vector<>::iterator в VS6 и VS2008
http://en.wikipedia.org/wiki/Std::vector
http://bytes.com/topic/c/answe... or-c-array
Помогите применить
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
05.03.2011, 19:57
Union, я писал уже как копировать, однакож кто читает?
Цитата Сообщение от novi4ok Посмотреть сообщение
::memcpy (int_buf, &*int_vect.begin(), sizeof(int)*2);
дикий угар на самом деле
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 20:22  [ТС]
alex_x_x извиняюсь, зациклился на записи, поэтому не стал читать после "обратные действия понятны"
Тем неменее в тех темах более полный код.
Мне уже кажется что записать в файл через memcpy по некоторым причинам не возможно...

Добавлено через 18 минут
Если это возможно, должно быть как-то так:
C++
1
2
3
4
     std::vector<uint32_t> v1;
     // Заполняем вектор
     std::ofstream ofs("2.dat", std::ios::binary);
     memcpy( &*v1.begin(), ofs, 1024 );
Само сабой это не работает.
И помоему копировать в дескриптор через memcpy некорректно...Наверно нужно использовать промежуточный буфер, который будет заполняться через memcpy, а далее уже через std::copy закидывать его в файл.
Я прав?
0
 Аватар для igorrr37
2893 / 2040 / 992
Регистрация: 21.12.2010
Сообщений: 3,790
Записей в блоге: 9
05.03.2011, 20:49
Union, какие ещё лишние операции?
reinterpret_cast<char*>(&v[0]) - приведение указателей. В memcpy будет неявное приведение к void*;
v.size()<<2 - вычисление размера vector<int> в байтах, для memcpy это тоже потребуется
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
05.03.2011, 21:02
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iterator>
 
int main()
{ 
  std::vector< int > v;
  for( int i=0;i<10;++i )
    v.push_back( i );
  int length = v.size() * sizeof( int );
 
  int fd = open( "1.txt", O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600 );
  if( -1 == fd )
    {
      perror( "cant open file" );
      return -1;
    }
  if( -1 == ftruncate( fd, length ) )
    {
      perror( "cant truncate file" );
      return -1;
    }
  void* base = mmap( 0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
  if( MAP_FAILED == base )
    {
      perror( "cant mapped file" );
      return -1;
    }
  memcpy( base, &v.front(), length );
  if( -1 == munmap( base, length ) )
    {
      perror( "error unmapping file" );
    }
  close( fd );
  v.clear();
 
  //unserialize file
  fd = open( "1.txt", O_RDWR, (mode_t)0600 );
  if( -1 == fd )
    {
      perror( "cant reopen file" );
      return -1;
    }
 
  base = mmap( 0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
  if( MAP_FAILED == base )
    {
      perror( "cant remapped file" );
      return -1;
    }
 
  v.resize( length / sizeof(int) );
  memcpy( &v.front(), base, length );
  
  std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " " ) );
  if( -1 == munmap( base, length ) )
    {
      perror( "error unmapping file" );
    }
  close( fd );
  
}
даже работает

Добавлено через 11 минут
igorrr37, все хорошо, но
Цитата Сообщение от igorrr37 Посмотреть сообщение
v.size()*4
плохо, v.size() * sizeof( int )
int разным по размеру бывает
1
19 / 11 / 0
Регистрация: 02.09.2010
Сообщений: 235
05.03.2011, 22:28
А зачем приведение указателей? Насколько мне известно memcpy разом копирует n байт, в то время как все остальные функции копируют побайтно.
Я так понял тс не хочет перебирать вектор итератором поэлементно, а хочет скопировать его целиком как единый кусок памяти, воспользовавшись свойством memcpy?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.03.2011, 22:28
Помогаю со студенческими работами здесь

Сериализация/Десериализация
В общем пытаюсь сохранить список, вылезает такое: An unhandled exception of type 'System.InvalidOperationException' occurred in...

Сериализация и десериализация
Есть класс: public class FilesData : ISerializable //класс, содержащий файлы { public struct fi ...

Сериализация и десериализация
Приветы! Есть клиент-серверное приложение (я подумал, что так будет удобнее всего работать) и есть задание: В одном приложении...

Сериализация / десериализация
доброе время суток=) такое задание - отправить объект класса с приложения клиента на сервер это код который сериализует на...

Сериализация/десериализация
Добрый день! Прошу помочь с сериализацией, нашла туториал, все сделала, как там написано, выдается куча ошибок. Выкладываю проект с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru