Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.88
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 16:26     Сериализация и десериализация vector'а int'ов #1
Имею вектор:
C++
1
std::vector<int> mig
Нужно очень быстро сохранить его в файл, а потом восстановить из файла, пользуясь тем фактом, что это вектор int'ов. Т.е. не содержет никаких структур и указателей на объекты вне самого вектора. Т.к. вектор находится в едином цельном куске памяти, то задача сводится к простому копированию этого участка памяти в файл. И потом обратно копирование всего файла в память.
Помогите пожалуйста реализовать
Спасибо
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.03.2011, 16:26     Сериализация и десериализация vector'а int'ов
Посмотрите здесь:

vector<Struct2{int,vector<struct1>}> или множественное наследование ... C++
C++ Указатель на объект вектор в векторе vector < vector<int>* >*
C++ error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Vector<int>::Vector<int>(void)" (?0?$Vector@H@@QAE@XZ) в функции _main
C++ set_difference(vector<pair<int,int>>, vector<int>>
C++ Записать числа из файла в двумерный массив или вектор вроде такого vector<vector<int>>
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
05.03.2011, 16:33     Сериализация и десериализация vector'а int'ов #2
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;
}
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 17:23  [ТС]     Сериализация и десериализация vector'а int'ов #3
Посмотрел данный метод, вектор записывается в файл поэлементно через разделитель \n + каждый элемент конвертируется из int в string. А можно ли как-нибудь записывать в бинарном виде? Нужна максимальная производительность, в приложении постоянно копируются вектора по 500-900 тыс элементов. М.б.можно как-то через memcpy сразу по нескольку элементов копировать?
Спасибо.

Добавлено через 27 минут
Можно ли записывать Int'ы без конвертации в строки? Int = 4 байта - записывать 4 байта и потом считывать по 4 байта. Тогда разделитель \n не нужен. Каждые 4 байта соответствуют одному элементу в векторе.
insolent
 Аватар для insolent
826 / 347 / 15
Регистрация: 30.01.2009
Сообщений: 1,204
05.03.2011, 18:12     Сериализация и десериализация vector'а int'ов #4
Union, открывай файл для бинарной записи.
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:02  [ТС]     Сериализация и десериализация vector'а int'ов #5
Это смао собой Меня интересует реализация алгоритма вцелом. Т.е. не только как записать, но и как потом восстановить. В приведенном примере восстанавливается через разделитель \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, без конвертации?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
05.03.2011, 19:18     Сериализация и десериализация vector'а int'ов #6
я не силен в данной теме, но соображения
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) )

под линь тоже маппинг делают, но тут уж не просвещен
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:26  [ТС]     Сериализация и десериализация vector'а int'ов #7
1) К сожалению это linux (Ubunta)
2) Размер записывать вовсе необязательно, я могу его сохранить отдельно, в базе. В общем вся задача сводится к банальному копированию участка памяти.
3) Я искал возможность через memcpy прямиком скопировать вектор, т.к. при данных условиях по быстродействию это решение было бы оптимальным, а поэлементное копирование, да ещё и спреобразованием - расточительство.
Пока про memcpy ничего не нашёл, жду, может кто здесь подскажет.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
05.03.2011, 19:31     Сериализация и десериализация vector'а int'ов #8
http://linux.die.net/man/2/mmap
http://www.cplusplus.com/reference/c...string/memcpy/
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:35  [ТС]     Сериализация и десериализация vector'а int'ов #9
Я в приложении часто использую memcpy с char'ами, но не имею никакого представления насчёт вектора. Мои знания насчёт вектора и stl вообще чисто поверхностные - это принцип работы, что такое итераторы и т.д. В общем я не знаю как применить memcpy в этой задаче...
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
05.03.2011, 19:37     Сериализация и десериализация vector'а int'ов #10
читает и пишет блок памяти вроде как
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();
}
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 19:46  [ТС]     Сериализация и десериализация vector'а int'ов #11
igorrr37 спасибо за пример, но опять же лишние операции используются...
Вот я нашел темы про копирование вектора через memcpy:
std::vector<>::iterator в VS6 и VS2008
http://en.wikipedia.org/wiki/Std::vector
http://bytes.com/topic/c/answers/849...vector-c-array
Помогите применить
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
05.03.2011, 19:57     Сериализация и десериализация vector'а int'ов #12
Union, я писал уже как копировать, однакож кто читает?
Цитата Сообщение от novi4ok Посмотреть сообщение
::memcpy (int_buf, &*int_vect.begin(), sizeof(int)*2);
дикий угар на самом деле
Union
 Аватар для Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
05.03.2011, 20:22  [ТС]     Сериализация и десериализация vector'а int'ов #13
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 закидывать его в файл.
Я прав?
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
05.03.2011, 20:49     Сериализация и десериализация vector'а int'ов #14
Union, какие ещё лишние операции?
reinterpret_cast<char*>(&v[0]) - приведение указателей. В memcpy будет неявное приведение к void*;
v.size()<<2 - вычисление размера vector<int> в байтах, для memcpy это тоже потребуется
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
05.03.2011, 21:02     Сериализация и десериализация vector'а int'ов #15
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 разным по размеру бывает
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.03.2011, 22:28     Сериализация и десериализация vector'а int'ов
Еще ссылки по теме:

C++ Сериализация и десериализация двусвязного списка
C++ Error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::Vector<int>(int,int,int)" (?0?$Vec
Как можно увеличить размер вектора, который является элементом вектора vector<vector<int>>arr(n, vector <int>) C++

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

Или воспользуйтесь поиском по форуму:
Damaks
18 / 10 / 1
Регистрация: 02.09.2010
Сообщений: 235
05.03.2011, 22:28     Сериализация и десериализация vector'а int'ов #16
А зачем приведение указателей? Насколько мне известно memcpy разом копирует n байт, в то время как все остальные функции копируют побайтно.
Я так понял тс не хочет перебирать вектор итератором поэлементно, а хочет скопировать его целиком как единый кусок памяти, воспользовавшись свойством memcpy?
Yandex
Объявления
05.03.2011, 22:28     Сериализация и десериализация vector'а int'ов
Ответ Создать тему
Опции темы

Текущее время: 23:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru