J'en serai peut-être à nouveau accro un jour, donc un mémorandum
Je développe toujours dans un environnement Linux 32 bits, mais j'étais accro à un certain système. Le système gère les fichiers avec un programme en langage C, Il gère une grande taille de plusieurs niveaux de Go, et quand je l'essaye, cela ne fonctionne pas du tout.
Comme le fichier est énorme, il faut du temps pour le reproduire une fois, et la cause que j'ai trouvée en déboguant tout en frustrant est très simple.
** Le fichier est trop volumineux pour être ouvert! ** **
Il semble que Linux 32 bits fait environ 2 Go. (Peut-être que mon environnement Eh bien, il y aura une limite supérieure, mais ce que vous rencontrerez réellement ... De plus, dans ce système, une application pour les programmes en langage C pour diviser les fichiers. Il ne peut même pas ouvrir le fichier. Je ne peux pas le croire ...
2018/04/23 PostScript Dans un commentaire de @ angel_p_57 J'ai entendu dire qu'il existe une option de compilation appelée ** _FILE_OFFSET_BITS **.
En suivant la page de manuel et le code OSS que j'avais, j'ai ajouté ce qui suit à CFLAGS afin que fopen puisse être fait en toute sécurité tel quel!
-D_FILE_OFFSET_BITS=64
Non, c'est merveilleux que vous puissiez changer le comportement avec une seule option, la glibc!
La ** commande split ** m'est venue après avoir étudié diverses méthodes de fractionnement de fichiers. Ceci est une commande pour fractionner des fichiers sous Linux, grâce à ceci Seule la commande de division a bien fonctionné.
Alors, comment devons-nous y faire face? Le mieux est de regarder le contenu du split, mais je n'ai pas le temps ** Créez un wrapper fopen en utilisant la commande split! ** **
Ouvrez IF au lieu de fopen, si la taille est grande, divisez-le avec / usr / bin / split et enregistrez-le dans le répertoire tmp → Au moment de fread, quand je suis allé à la fin pendant fread, j'ai ouvert le fichier suivant et lu la suite.
//fopenのラッパー
void * large_freader_open(const char *path, unsigned long maxsize) {
//....
//サイズを見て、大きすぎたらseparate_fileでファイル分割
unsigned long fsize = get_size(path);
if(fsize<=maxsize) {
//same as fopen
handle->fp=fopen(path, "r");
handle->max_index=1;
} else {
//separate file and open file as order
separate_file(path, maxsize, handle);
handle->fp = freader_fopen(handle);
}
//..
// return renvoie la structure interne au lieu de FILE *
return handle;
//..
}
static void separate_file(const char *path, unsigned long maxsize, struct large_freader_s *handle) {
//...
//tmpディレクトリを取得してファイル分割
char name[FNAME_MAX];
get_current_dirname(handle, name, FNAME_MAX);
snprintf(cmd, sizeof(cmd), "/usr/bin/split -d --suffix-length=6 -b %lu %s %s", maxsize, path, name);
//...
}
//freadのラッパー
size_t large_freader_read(void * prt, size_t size,void * stream) {
//...
//普通にfreadして
size_t ret = fread(prt, 1, size, handle->fp);
if(ret == size) {
//read success, return normaly
return ret;
}
//サイズ分読んでないなら次のファイルに移動
freader_fclose(handle);
//move to next
handle->cur_index++;
//全ファイル読んでるなら終わり
if(IS_LAST_FILE(handle)) {
//finish to read
return ret;
}
//そうじゃないなら次をopenしてread
handle->fp = freader_fopen(handle);
if(handle->fp) {
ret += fread(((char *)prt)+ret, 1, size-ret, handle->fp);
}
return ret;
}
//内部でのfopen処理
static FILE * freader_fopen(struct large_freader_s *handle) {
//splitしたファイル名を取得してfopen。close時にはファイル削除します。
char dname[FNAME_MAX];
get_current_fname(handle, dname, FNAME_MAX);
return fopen(dname, "r");
}
Je l'ai créé chez moi pendant la nuit et l'ai publié sur github. Je voulais aussi diviser le fichier au moment de la rédaction, c'est donc une bibliothèque wrapper pour la lecture / écriture. Maintenant qu'il y a -D_FILE_OFFSET_BITS = 64, seule l'écriture peut être utilisée ...
https://github.com/developer-kikikaikai/read_write_wrapper
Mon PC domestique est 64 bits et je n'ai pas pu l'essayer fermement avec 32 bits, je vais donc résoudre les problèmes que j'ai remarqués lorsque j'ai essayé de l'utiliser dans un autre environnement.
2018/04/23 PostScript ・ Si quelque chose d'inattendu se produit, vérifiez d'abord les options de compilation!
Autrement, ・ Puisque fopen ne peut pas être utilisé, il est très désagréable de devoir faire popen → ls pour obtenir la taille. ・ Je crains de garantir le fonctionnement dans un environnement 32 bits ・ Il s'agit de la limite d'un système 32 bits, vous devriez donc faire de votre mieux, non? etc Vous devez compter sur une solution merdique.