Comment puis-je écrire «un bit» dans un flux de fichier ou une structure de fichier à chaque fois? est-il possible d'écrire dans une file d'attente puis de la vider? est-ce possible avec C# ou java? cela était nécessaire lorsque j'ai essayé d'implémenter une instance de codage Huffman. Je ne peux pas écrire des bits dans des fichiers. écrivez-les donc sur un bitset puis (une fois la compression terminée) écrivez-en 8 bits à chaque fois (en excluant la dernière).écrire des «bits» dans les flux de fichiers C++
Répondre
les Buffering bits individuels jusqu'à ce que vous avez accumulé un octet tout semble être une bonne idée:
byte b;
int s;
void WriteBit(bool x)
{
b |= (x ? 1 : 0) << s;
s++;
if (s == 8)
{
WriteByte(b);
b = 0;
s = 0;
}
}
Il vous suffit de traiter le cas où le nombre de bits à écrire est pas un multiple de huit.
Ça a l'air bien. Le dernier cas pourrait être manipulé avec un argument 'bool flush' et' if (s == 8 || flush) 'aussi. –
Assurez-vous simplement que s est initialisé à 0. –
Notez également qu'aucun bit "premier" ou "dernier" dans un octet n'est défini ou implicite dans la norme C, juste le plus ou le moins significatif, peut-être "gauche" et "droite" cela concerne les changements. Donc, WriteBit devra décider pour lui-même (et le document) si les bits doivent être écrits les plus ou les moins significatifs en premier. Vous êtes allé pour le moins significatif, ce qui est assez juste et Wikipedia prétend que c'est de loin le plus commun au niveau du matériel pour les communications série. Je ne l'ai jamais fait assez profond dans un pilote de série pour savoir pour moi-même. –
Quel système de fichiers utilisez-vous? Il est probable qu'il stocke la longueur du fichier en octets (y a-t-il qui ne le fait pas?), Il est donc impossible d'avoir un fichier physique qui ne soit pas un nombre entier d'octets. Par conséquent, si vous écrivez dans le fichier sous la forme d'un flux de bits, vous devez soit tronquer les derniers bits lorsque vous avez terminé, soit écrire l'octet final avec ce qui est ammount to junk dans les bits restants.
Voici quelques code Python pour vous lancer
class BitFile(file):
def __init__(self, filename, mode):
super(BitFile, self).__init__(filename, mode)
self.bitCount=0
self.byte = 0
def write(self, bit):
self.bitCount+=1
self.byte = self.byte*2+bit
if self.bitCount%8==0:
super(BitFile, self).write(chr(self.byte))
self.byte=0
def close(self):
if self.bitCount%8!=0:
super(BitFile, self).write(chr(self.byte))
super(BitFile, self).close()
with BitFile("bitfile.bin","w") as bf:
bf.write(1)
bf.write(1)
bf.write(1)
bf.write(0)
bf.write(0)
bf.write(0)
bf.write(0)
bf.write(0)
bf.write(1)
Vous ne pouvez pas vraiment. Je suis assez sûr que le problème n'est pas avec la langue ou le système de fichiers, mais un problème matériel. Les processeurs sont conçus pour fonctionner avec des octets. Probablement le plus proche que vous pouvez faire est d'écrire votre dernier octet encore et encore, droite rembourré avec des zéros, en les changeant comme vous allez, un à la fois.
ainsi écrire des bits « 11011 », vous pouvez faire ce qui suit (exemple de python, mais ne importe quelle langue devrait avoir des installations pour le faire:
f.write(chr(0b10000000))
f.flush()
f.seek(-1)
f.write(chr(0b11000000))
f.flush()
f.seek(-1)
f.write(chr(0b11000000))
f.flush()
f.seek(-1)
f.write(chr(0b11010000))
f.flush()
f.seek(-1)
f.write(chr(0b11011000))
f.flush()
Vous ne avez pas l'espoir d'obtenir une sorte de gain de performance de ce étiez-vous?
FYI, les langages C et C++ n'ont pas de possibilités pour déclarer des constantes binaires. –
Je recommande l'attribution d'un tampon assez grand (4096 octets au moins) et rincez que hors le disque chaque fois qu'il remplit. L'utilisation d'un tampon d'un octet provoque généralement une mauvaise performance.
si je veux compresser un fichier énorme, comme un glyphe pos données d'otf arabe. sa taille est de 48 Mo, après copmressing est de 29 Mo. Donc, votre méthode n'est pas théorique. et gaspille de la mémoire. –
Vous avez mal compris ma méthode. Je suggère simplement un tampon plus grand qu'un octet, pour que la vidange soit beaucoup moins fréquente, et non pas un tampon pour l'ensemble de vos données. – Tronic
I l'a fait une fois pour décodage Huffman et fini écrire les bits comme caractères et ainsi gérer tout en interne comme une simple chaîne de caractères en C. De cette façon, vous n'avez pas à vous inquiéter de l'octet de queue et il est également lisible par l'utilisateur. Il est également plus facile de vérifier les bits car il suffit d'adresser le tableau char (binbuf[123] == '1'
) au lieu de manipuler des bits. Pas la solution la plus optimisée, mais elle a résolu mon problème soigneusement.
L'inconvénient évident est que cette représentation utilise plus de mémoire.
Vous pouvez utiliser boost::dynamic_bitset
avec std::ostream_iterator
pour obtenir le résultat souhaité d'une manière concise:
#include <fstream>
#include <iterator>
#include <boost/dynamic_bitset.hpp>
typedef boost::dynamic_bitset<unsigned char> Bitset;
// To help populate the bitset with literals */
Bitset& operator<<(Bitset& lhs, bool val) {lhs.push_back(val); return lhs;}
int main()
{
Bitset bitset;
bitset<<0<<1<<0<<1<<0<<1<<0<<1
<<1<<0<<1<<0;
std::ofstream os("data.dat", std::ios::binary);
std::ostream_iterator<char> osit(os);
boost::to_block_range(bitset, osit);
return 0;
}
J'ai fait la taille du bloc de mes dynamic_bitset
8 bits en spécifiant unsigned char
comme paramètre de modèle.Vous pouvez agrandir la taille du bloc en spécifiant un type entier plus grand.
boost::to_block_range
vide l'ensemble de bits en blocs vers l'itérateur de sortie donné. S'il y a des bits restants vides dans le dernier bloc, ils seront complétés avec zéro.
Lorsque j'ouvre data.dat dans un éditeur hexadécimal, je vois: AA 05
. C'est sur une petite plate-forme d'Endian (x64).
Le problème ici est que de nombreuses plates-formes n'ont pas d'accès direct aux bits. Ils regroupent les bits dans un paquet minimal, souvent le octet ou le mot. En outre, le protocole pour les dispositifs de flux ne facilite pas la transmission de bits individuels.
La méthode courante pour traiter des bits individuels consiste à les empaqueter dans la plus petite unité portable et accessible (adressable). Les bits inutilisés sont généralement mis à zéro. Cela peut être accompli avec des opérations arithmétiques binaires (OR, AND, EXCLUSIVE-OR, NOT, etc.).
Avec les processeurs modernes, le trépan ralentit la machine et la performance. La mémoire est bon marché et avec de grands espaces d'adressage, la justification de l'empaquetage est devenue plus difficile. Généralement, l'empaquetage est réservé aux opérations orientées matériel (et aussi aux protocoles de transmission). Par exemple, si la capacité du mot d'un processeur est de 16 bits, le processeur peut probablement gérer 16 mots plus rapidement que les manipulations 16 bits en un seul mot. De plus, gardez à l'esprit que l'écriture vers et depuis la mémoire est souvent plus rapide que les E/S des flux. Les systèmes efficaces tamponnent les données en mémoire avant de transmettre les données. Vous pouvez vouloir considérer cette technique dans vos conceptions. La réduction des opérations d'E/S améliorera les performances de votre programme.
- 1. Comment écrire/lire des bits de/vers un flux? (C#)
- 2. Écrire tous les bits en C#
- 3. Comment écrire des bits dans un fichier?
- 4. C# rijndael CryptoStream puis-je écrire dans les fichiers bits et bits comme le fait le textwriter?
- 5. Lire (/ écrire) des fichiers en C#
- 6. signale une erreur dans les flux de fichiers dans C++
- 7. Écrire dans des fichiers groupés?
- 8. Flux de fichiers plus importants utilisant C#
- 9. chaînage des flux C++
- 10. Écrire un flux de travail Workflow Foundation avec C#
- 11. Performances des flux de chaînes par rapport aux flux d'E/S de fichiers en C++
- 12. Comment écrire dans les fichiers journaux Tomcat
- 13. aide pour écrire des fichiers dans java
- 14. Accès aux flux de données alternatifs dans les fichiers
- 15. Comment écrire des fichiers XML?
- 16. Écrire des fichiers temporaires dans l'application iPhone
- 17. Écrire StringBuilder au flux
- 18. problème avec flux de fichiers/fstream dans Xcode C++
- 19. Problèmes avec les fichiers d'E/S lors du portage des anciennes bibliothèques 'C' de 32 bits à 64 bits
- 20. comment écrire des fichiers vidéo MPEG4 de flux en vC++ DirectShow
- 21. Comment écrire correctement des fichiers dynamiques sur un serveur FTP?
- 22. Écrire des fichiers binaires en utilisant SAS?
- 23. Comment écrire des fichiers d'en-tête pour les périphériques
- 24. Traitement des fichiers C++
- 25. Flux C++ Boost io, gestion des erreurs
- 26. Comment gérer les accès simultanés aux fichiers avec un flux de fichiers/flux de données?
- 27. MSBuild - Écrire des caractères d'échappement dans des fichiers
- 28. Comment écrire de l'arabe dans les fichiers source Perl?
- 29. C#: conversion manuelle des bits?
- 30. Génération de fichiers .tlb dans Windows 7 Pro 32 bits
Avez-vous manqué une langue? La plupart des langues ne permettent pas d'écrire moins d'un octet à la fois. Vous pouvez tester des bits individuels et imprimer les résultats. – dirkgently