2010-02-28 13 views
6

Bene, il tema "Endianness" mi ha sempre dato un po 'di confusione, ma non ho mai dovuto affrontare problemi che mi hanno costretto a pensare al comportamento predefinito degli scrittori/lettori binari che ho usato. Sto scrivendo un decoder PNG in C# in questo momento. La specifica del formato di file PNG afferma che tutti i numeri sono memorizzati in una notazione big endian (che trovo molto naturale). Tuttavia, sono rimasto molto sorpreso quando ho notato che BinaryReader/Writer di .NET funziona con una notazione little endian. Ciò che mi ha confuso ancora di più è stato il fatto che l'IO binario di java funziona con una notazione big endian (non sono un programmatore java, quindi forse ho torto). Così ho iniziato a pensare alle seguenti domande:Endianness nei linguaggi di programmazione

1 - Perché le cose sono come sono? Intendo un comportamento predefinito della libreria di classi base. 2 - Perché non c'è modo di scegliere una notazione preferita quando si utilizza System.IO di .NET.

Attualmente sto usando Jon Skeet'sMiscUtil e funziona come un incantesimo (grazie, man =)). Ma sarebbe bello vedere questa funzionalità in una libreria di classi base.

+0

Che cos'è un BCL ..? –

+0

Libreria di classi base – n535

+0

Inoltre, trovo che big endian sia il più naturale. –

risposta

10

Questo perché il codice è pensato per funzionare nel modo migliore possibile sulla piattaforma più importante. C# /. NET è di Microsoft e viene eseguito principalmente su piattaforme x86. x86 è little-endian, quindi ha senso rendere la libreria little-endian. Java è prodotto da Sun e il Sun SPARC era big-endian, quindi lo standard Java era invece big-endian.

+0

E i quadri compatti e micro? Anche se, sono d'accordo, questo potrebbe essere stato un fattore, .NET, la natura è un pò indipendente dalla piattaforma. – n535

+2

Java è stato progettato per essere indipendente dalla piattaforma, motivo per cui sono andati con l'ordinamento più naturale. .NET viene in secondo luogo dalla sua indipendenza dalla piattaforma ed è stato progettato principalmente per normalizzare i vari linguaggi sulla piattaforma Windows e portare nuove funzionalità linguistiche come la garbage collection, ecc. Il mondo MS/Intel tende a essere miope in questo modo e quindi la maggior parte dei file che un programmatore di Windows dovrebbe leggere sono little endian. Little Endian è/era l'ordine preferito sui chip Intel. – PSpeed

+0

+1 Beh, questo ha un senso, ovviamente, ma non spiega l'assenza di scelta. Non vale nulla per implementare questo in un BCL in un modo molto efficiente. – n535

2

Il BCL contiene elementi nella classe statica System.BitConverter che consente di gestire il sistema endianness. Di conseguenza, tutti i metodi in BitConverter sono sostanzialmente indipendenti dalla piattaforma.

Inoltre, il metodo System.Net.IPAddress.NetworkToHostOrder consente di modificare l'endianità da big a little endian e viceversa.

+0

Qualcosa tranne la proprietà IsLittleEndian? System.Net.IPAddress.NetworkToHostOrder è molto lontano dal vero problema se – n535

+0

non sono sicuro di aver capito il tuo problema. Leggo e scrivo sempre file binari con BinaryReader e BinaryWriter, e se l'ordine dei byte non viene letto o scritto nel modo che voglio, basta scambiare i byte (di solito usando 'NetworkToHostOrder'). Qual è il grosso problema? –

+0

Bene, non esiste un vero "problema". In effetti, puoi lavorare con PNG in .NET, quindi penso che anche gli sviluppatori core di .NET non abbiano problemi. Ma sono anche preoccupato, che sarà più efficace interpretare i byte correttamente al volo (durante la lettura) senza ulteriori inversioni. Naturalmente, non è così difficile da implementare da solo, ma penso che tali cose dovrebbero essere fornite all'interno di un framework, solo perché sono abbastanza comuni (che spiegano l'esistenza di cose come MiscUtil). L'unica cosa che sto cercando di capire, ci sono alcuni motivi seri, perché non abbiamo questo in NET – n535

1

immagino che si riduce a sempre essere in grado di affrontare sia , indipendentemente dalla piattaforma in cui siete. Preon sta tentando di nascondere parte di tale complessità consentendo di dichiarare in modo dichiarativo (utilizzando le annotazioni) la mappatura tra la rappresentazione dei dati in memoria e la rappresentazione codificata.

Quindi, se questo è parte della vostra struttura di dati:

public Image { 
    int width; 
    int height; 
} 

quindi definire la mappatura ad una rappresentazione naturale big endian sarebbe facile come questo:

public Image { 
    @BoundNumber int width; 
    @BoundNumber int height; 
} 

Tuttavia, se la rappresentazione è little endian, quindi puoi farlo:

public Image { 
    @BoundNumber(byteOrder=LittleEndian) int width; 
    @BoundNumber(byteOrder=LittleEndian) int height; 
} 

In entrambi i casi, creando un Il codec per questa struttura dati è lo stesso:

Codec<Image> codec = Codecs.create(Image.class); 

So che alcune persone stavano parlando di portarlo anche su .NET.

Problemi correlati