2008-11-16 9 views
16

Il y a quelques semaines, j'utilisais std :: ifstream pour lire certains fichiers et il échouait immédiatement à l'ouverture car le fichier dépassait les 4 Go. À l'époque je ne pouvais pas trouver une réponse décente quant à la raison pour laquelle il était limité à des tailles de fichiers de 32 bits, alors j'ai écrit le mien en utilisant l'API OS native.Lire des fichiers de plus de 4 Go en utilisant C++ stl

Alors, ma question: Y at-il un moyen de gérer des fichiers de plus de 4 Go en taille à l'aide std :: ifstream/std :: ostream (IE: C++ standard)

EDIT: Utilisation de la mise en œuvre du TSL de la VC 9 compilateur (Visual Studio 2008). EDIT2: Il doit sûrement y avoir un moyen standard de prendre en charge les tailles de fichiers supérieures à 4 Go.

+0

STL pas particulièrement pertinent à cette question; l'enlever? Je suggérerais iostreams est le nom de la partie de la bibliothèque standard C++ dont vous parlez. – Alastair

+0

Retaillé comme Alastair suggéré. Et pour répondre, la norme ne dit rien sur la façon dont les fichiers volumineux devraient être supportés, ni sur la taille de size_t.C'est entièrement défini par l'implémentation. Alors, quelle implémentation utilisez-vous? – jalf

+0

Le titre de la question doit également être modifié. –

Répondre

13

Apparemment, cela dépend de la façon dont off_t est implémenté par la bibliothèque.

#include <streambuf> 
__int64_t temp=std::numeric_limits<std::streamsize>::max(); 

vous donne le maximum actuel.

STLport prend en charge les fichiers plus volumineux.

5

J'ai rencontré ce problème il y a plusieurs années en utilisant gcc sous Linux. Le système d'exploitation supportait les gros fichiers, et la bibliothèque C (fopen, etc.) le supportait, mais pas la bibliothèque standard C++. Je me suis avéré que j'ai dû recompiler la bibliothèque standard C++ en utilisant les bons indicateurs de compilation.

+1

Je suis avec vous KeithB, cela a _NOTHING_ todo avec tout problème de MSVC/STL ou autre, c'est un problème de déploiement du système. Le code source pour les bibliothèques CRT/STL est inclus avec le compilateur pour une raison, vous devrez peut-être # définir la macro de prépresse appropriée pour obtenir la fonctionnalité désirée. Ce n'est pas que la bibliothèque implémente l'un ou l'autre (par exemple * nix utilisant fgetpos ou fgetpos64 pour des fichiers> 32 bits), la bibliothèque supporte BOTH, c'est au développeur d'utiliser correctement la bibliothèque. Utilisation de STLPort est la même chose qu'une recompilation de la STL MSVC de toute façon, les deux impliquent un peu de réglages manuels – RandomNickName42

2

Du point de vue standard, rien n'empêche cela. Cependant, en réalité, la plupart des implémentations 32 bits utilisent 32 bits pour std::size_t. Maintenant, la norme C++ exige que l'allocateur standard dans la bibliothèque standard C++ utilise std :: size_t comme quantité de taille. Ainsi, vous êtes limité à 2^32 octets de stockage pour les conteneurs, les chaînes et autres. La situation pourrait être une autre pour std::off_t, je ne sais pas exactement ce qui se passe là-bas.

Vous devez utiliser l'API native du système d'exploitation directement, ou une bibliothèque l'enveloppant, pour pouvoir le faire, sans avoir à faire confiance aux implémentations de la bibliothèque standard, qui dépendent largement de l'implémentation.

+0

J'ai fini par emballer l'API OS directement pour le cas où la taille de mon fichier était supérieure à 4 Go – Raindog

0

Si vous pouvez vous éloigner de l'utilisation du standard C++ uniquement, alors vous pourriez être intéressé par boost::iostreams.

0

Au moins dans VS2013, le flux de fichiers standard C++ fonctionne bien avec des fichiers volumineux (> 4 Go).

J'ai testé sur VS2013 (avec update3).

int64_t file_pos = 4LL * 1024 * 1024 * 1024 + 1; 
file.seekp(file_pos, SEEK_SET); 
assert(file); 
cout << "cur pos: " << file.tellp() << endl; // the output is: 4294967297(4GB + 1) 

Le lien suivant est une confirmation supplémentaire que c'est un bug a été corrigé: https://connect.microsoft.com/VisualStudio/feedback/details/627639/std-fstream-use-32-bit-int-as-pos-type-even-on-x64-platform

pour courte: Stephan T. Lavavej (Visual Bibliothèques C++ Developer) dit

Nous l'avons corrigé, et le correctif sera disponible dans VC11 ... donc la prise en charge des fichiers volumineux devrait fonctionner correctement maintenant (indépendamment de la plate-forme x86/x64)