[c++] steams + file>2Gb

Maurog

возможно ли с помощью стримов открывать большие файлы? каким образом?
вот для fopen все попроще-там либо перехода на 64 бит хватает, либо в компилятор ключик -D_FILE_OFFSET_64 (или типа того)
но мне нужно для стримов ;(
пс: большие файлы-это больше 2Гигобайт

Maurog

что никто не секет чтоли?

Dasar

а в чем проблема?
stream либо сразу умеет работать с большими файлами, либо после замены traits

Maurog

streampos имеет тип лонг
поэтому я не знаю как стримы вообще могут работать с большими файлами
filebuf g;
g.open("bigfile","r") выдает NULL
поэтому не могу стримами пользоваться
хотя в манах вообще ничего про ограничения файлов нету ;(
я не знаю что такое traits
тут желательно поподробнее

Dasar

например, istream - Это basic_istream со стандартными traits
traits - определяют тип символа, тип смещения, тип размера файла и т.д.
соответственно, можно объявить свой stream со своим traits, в котором будет указано, что тип размера файла __int64


template<class _Elem>
struct char_traits_int64size:
public _Char_traits_base
{ // properties of a string or stream element
typedef _Elem char_type;
typedef long int_type;
// typedef streampos pos_type;
// typedef streamoff off_type;
typedef __int64 pos_type;
typedef __int64 off_type;
typedef _Mbstatet state_type;
static void __CLRCALL_OR_CDECL assign(_Elem& _Left, const _Elem& _Right)
{ // assign an element
_Left = _Right;
}
static bool __CLRCALL_OR_CDECL eq(const _Elem& _Left, const _Elem& _Right)
{ // test for element equality
return (_Left == _Right);
}
static bool __CLRCALL_OR_CDECL lt(const _Elem& _Left, const _Elem& _Right)
{ // test if _Left precedes _Right
return (_Left < _Right);
}
static int __CLRCALL_OR_CDECL compare(const _Elem *_First1,
const _Elem *_First2, size_t _Count)
{ // compare [_First1, _First1 + _Count) with [_First2, ...)
// _DEBUG_POINTER(_First1);
// _DEBUG_POINTER(_First2);
for (; 0 < _Count; --_Count, ++_First1, ++_First2)
if (!eq(*_First1, *_First2
return (lt(*_First1, *_First2) ? -1 : +1);
return (0);
}
static size_t __CLRCALL_OR_CDECL length(const _Elem *_First)
{ // find length of null-terminated sequence
// _DEBUG_POINTER(_First);
size_t _Count;
for (_Count = 0; !eq(*_First, _Elem; ++_First)
++_Count;
return (_Count);
}
_SCL_INSECURE_DEPRECATE
static _Elem *__CLRCALL_OR_CDECL copy(_Elem *_First1,
const _Elem *_First2, size_t _Count)
{ // copy [_First1, _First1 + _Count) to [_First2, ...)
// assume there is enough space in the destination buffer
return _Copy_s(_First1, _Count, _First2, _Count);
}
static _Elem *__CLRCALL_OR_CDECL _Copy_s(_Elem *_First1, size_t _Dest_size,
const _Elem *_First2, size_t _Count)
{ // copy [_First1, _First1 + _Count) to [_First2, ...)
// _DEBUG_POINTER(_First1);
// _DEBUG_POINTER(_First2);
_SCL_SECURE_CRT_VALIDATE(_Dest_size >= _Count, NULL);
_Elem *_Next = _First1;
for (; 0 < _Count; --_Count, ++_Next, ++_First2)
assign(*_Next, *_First2);
return (_First1);
}
static const _Elem *__CLRCALL_OR_CDECL find(const _Elem *_First,
size_t _Count, const _Elem& _Ch)
{ // look for _Ch in [_First, _First + _Count)
// _DEBUG_POINTER(_First);
for (; 0 < _Count; --_Count, ++_First)
if (eq(*_First, _Ch
return (_First);
return (0);
}
_SCL_INSECURE_DEPRECATE
static _Elem *__CLRCALL_OR_CDECL move(_Elem *_First1,
const _Elem *_First2, size_t _Count)
{ // move [_First1, _First1 + _Count) to [_First2, ...)
// assume there is enough space in the destination buffer
return _Move_s(_First1, _Count, _First2, _Count);
}
static _Elem *__CLRCALL_OR_CDECL _Move_s(_Elem *_First1, size_t _Dest_size,
const _Elem *_First2, size_t _Count)
{ // move [_First1, _First1 + _Count) to [_First2, ...)
// _DEBUG_POINTER(_First1);
// _DEBUG_POINTER(_First2);
_SCL_SECURE_CRT_VALIDATE(_Dest_size >= _Count, NULL);
_Elem *_Next = _First1;
if (_First2 < _Next && _Next < _First2 + _Count)
for (_Next += _Count, _First2 += _Count; 0 < _Count; --_Count)
assign(*--_Next, *--_First2);
else
for (; 0 < _Count; --_Count, ++_Next, ++_First2)
assign(*_Next, *_First2);
return (_First1);
}
static _Elem *__CLRCALL_OR_CDECL assign(_Elem *_First,
size_t _Count, _Elem _Ch)
{ // assign _Count * _Ch to [_First, ...)
// _DEBUG_POINTER(_First);
_Elem *_Next = _First;
for (; 0 < _Count; --_Count, ++_Next)
assign(*_Next, _Ch);
return (_First);
}
static _Elem __CLRCALL_OR_CDECL to_char_type(const int_type& _Meta)
{ // convert metacharacter to character
return _Elem)_Meta);
}
static int_type __CLRCALL_OR_CDECL to_int_type(const _Elem& _Ch)
{ // convert character to metacharacter
return int_type)_Ch);
}
static bool __CLRCALL_OR_CDECL eq_int_type(const int_type& _Left,
const int_type& _Right)
{ // test for metacharacter equality
return (_Left == _Right);
}
static int_type __CLRCALL_OR_CDECL eof
{ // return end-of-file metacharacter
return int_type)EOF);
}
static int_type __CLRCALL_OR_CDECL not_eof(const int_type& _Meta)
{ // return anything but EOF
return (_Meta != eof ? (int_type)_Meta : (int_type)!eof;
}
};
typedef basic_istream<char, char_traits_int64size<char> > stream64;

Maurog

ясна
значит стримами нельзя ;(
мне же либы уже готовые надо линковать
а не высирать свои

Dasar

Так вроде и есть использование стандартных либ:


template class char_traits_size64<Elem>:char_traits<Elem>
{
typedef __int64 pos_type;
typedef __int64 off_type;
}
typedef basic_iostream<char, char_traits_size64<char> > iostream64;


Далее юзаешь stream64.

freezer

может так?


template <class Elem> class char_traits_size64:char_traits<Elem>

Maurog

это точно повлияет на всякие
typedef long streampos
которые прописаны во многих .h семейства стримов?

Dasar

> может так?
согласен

Dasar

Это влияет только на тот стрим, который ты используешь.
Зачем это должно влиять на другие стримы?

Maurog

что-то мучают меня сомнения, что это поможет
вот в этих строчках
filebuf g;
g.open("bigfile");
какой стрим я юзаю?
.open не срабатывает
пс. всем пасиба...я попробую такие фишки

Dasar

пиши так:


basic_filebuf<char, char_traits_size64<char> > g;
g.open("bigfile");

Maurog

ооо
стильно
спасибо)

Maurog

ne kompiliruetsya
Error: "," expected instead of
"iostream64".

rosali

Код запости?

Maurog

template <class Elem> class char_traits_size64:char_traits_int64size<Elem>
{
typedef __int64 pos_type;
typedef __int64 off_type;
};
typedef basic_iostream <char, char_traits_size64<char> > iostream64;

rosali

если ты
#include <iostream>
а не
#include <iosteam.h>
то надо писать
std::basic_iostream
Это?
PS. А что такое char_traits_int64size ?

Maurog

a pered etim:
template<class _Elem>
struct char_traits_int64size:
public _Char_traits_base
{
//tochnaya copy-paste ot darkgray
};
//inet ne pozvolyaet zapostit' eto -

rosali

А, ну тогда еще наследование
class char_traits_size64:char_traits_int64size<Elem>
не помешало бы публичным сделать...
И typedef-ы в public...
Ммм, проще вместо class struct написать

Maurog

ty luchshe code napishi kak dumaesh pravilnee budet
ato ya tak ne soobrazhayu-

rosali

Я вообще-то не знаю, что такое _Char_traits_base, а вот такое у меня компилируется:


#include <fstream>
template <class Elem> struct char_traits_size64
{
typedef __int64 pos_type;
typedef __int64 off_type;
};
typedef std::basic_fstream <char, char_traits_size64<char> > fstream64;
//fstream64 ios("large.txt");


А если последнюю строчку раскомментировать, то уже не компилицца, потому что дейсвительно в traits-ах должно быть еще дофига других typedef-ов...

Maurog

ya ne mogu takoy #include sdelat'
rabotaet tolko <stream.h>
nu i vydayutsya oshibki (
ne nravitsya emu takoy typedef =(
Error: std is not defined.
"my.cc", line 145: Error: "," expected instead of
"fstream64".

rosali

<stream.h> вместо <stream> -- это значит у тебя старый STL... я не знаю что в нем есть а чего нет
Оставить комментарий
Имя или ник:
Комментарий: