2009-09-14 19 views
19

Yani burada anlaşma var dizeye bayt dizisi dönüştürme ve: Ben başlığındaki bazı meta verilerle bir dizeye yüzden can karışıklık dönüştürmek, (bayt) bir dosyayı açmaya çalışıyorum, geri dönüştürmek bayt için ve kaydedin. Şu an koştuğum problem bu kodla. Özgün bayt dizisine geri ve ileri (ancak başka şekilde değiştirilmemiş) dönüştürülen dizgiyi karşılaştırdığımda, bu eşitsizdir. Bu işi nasıl yapabilirim?C# tekrar

public static byte[] StringToByteArray(string str) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    return encoding.GetBytes(str); 
} 

public string ByteArrayToString(byte[] input) 
{ 
    UTF8Encoding enc = new UTF8Encoding(); 
    string str = enc.GetString(input); 
    return str; 
} 

İşte bunları nasıl karşılaştırıyorum.

byte[] fileData = GetBinaryData(filesindir[0], Convert.ToInt32(fi.Length)); 
string fileDataString = ByteArrayToString(fileData); 
byte[] recapturedBytes = StringToByteArray(fileDataString); 
Response.Write((fileData == recapturedBytes)); 

Ben kullanarak, UTF-8 eminim:

"System.Text.UTF8Encoding" döndürür
StreamReader sr = new StreamReader(filesindir[0]); 
Response.Write(sr.CurrentEncoding); 

.

+6

UTF-8'in başlayacağından emin misiniz? –

+0

Emin değilim. Olup olmadığımı nasıl anlarım? –

+0

Ne demek, eşitsiz mi? Dizininiz eşit değil mi? aynı ipucu sonucunu almazsınız? – Khan

cevap

16

çeşitli kodlamaların örneklerini sunar Encoding sınıfın statik işlevleri deneyin. Sadece bir bayt dizisine dönüştürmek için Encoding'u başlatmanız gerekmez. Dizeleri kodda nasıl karşılaştırıyorsunuz?

Sen diziler, değil dizeleri kıyaslıyorsun

Düzen. Eşitsizler çünkü iki farklı diziye işaret ediyorlar; == operatörünü kullanarak yalnızca referanslarını değil, değerlerini karşılaştırır. Eşdeğer olup olmadığını belirlemek için dizinin her öğesini denetlemeniz gerekir.

public bool CompareByteArrays(byte[] lValue, byte[] rValue) 
{ 
    if(lValue == rValue) return true; // referentially equal 
    if(lValue == null || rValue == null) return false; // one is null, the other is not 
    if(lValue.Length != rValue.Length) return false; // different lengths 

    for(int i = 0; i < lValue.Length; i++) 
    { 
     if(lValue[i] != rValue[i]) return false; 
    } 

    return true; 
} 
+0

Sorunun nasıl düzenlendiğini göstermek için soruyu düzenledim. –

+0

Bunu denedim, aynı uzunlukta olmadıklarını geri döndürdüler. Başka bir yerde olmalı. –

+3

UTF8 kodlaması için belgelere bakın. Önsözün belirtilip belirtilmeyeceğine dair bir seçenek var. Oluşturulan bayt dizininizin orijinalden daha uzun olduğunu tespit ederseniz, muhtemelen bu sizin sorununuz olur. Yine, UTF8'in aslında doğru kodlama olduğundan emin olmanız gerekir. Nasıl anlatacağınıza gelince, size veriyi kimin vereceğini sormalısınız. –

3

Senin sorunun, bayt dizisi kıyaslıyorsun yol olarak görünür: Eğer bayt dizinin adresini karşılaştırarak konum beri

Response.Write((fileData == recapturedBytes)); 

Bu her zaman return false olur, değil içerdiği değerler. Dize verilerini karşılaştırın veya bayt dizilerini karşılaştırmak için bir yöntem kullanın. yapmanız gerekir, hatta girişimi için

Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes)); 
5

nedeniyle .NET dizeleri Unicode dizelerini kullanması nedeniyle, artık bu gibi insanlar Çoğu durumda C yaptığı yapabilirsiniz: Ayrıca yerine bu yapabilirdi < -> byte dizisinden geri dönmek için içerikler aslında metinleri.

Ben açıkça bu noktayı yapmak zorunda: byte[] veri metin değilse, .NET, ardından metin üzerinde ikili veri için özel Base64 kodlama haricinde bir string dönüştürmek çalışmayın kanal. Bu, .NET'te çalışan insanlar arasında yaygın bir yanlış anlaşılmadır. Eğer ham bayt (8 bit muhtemelen-yazdırılabilir değil karakter) ve bir .NET dizesi olarak bunları işlemek ve bayt içine geri çevirmek istediğinizde

+4

Dize <-> byte [] dönüşümleri genellikle, BitConverter sınıfından değil, System.Text.Encoding sınıflarından biri aracılığıyla gerçekleştirilmelidir. BitConverter.ToString, bir bayt dizisini sayıların onaltılık bir dizgisi temsiline dönüştürür, ** bir bayt dizisini bir dizeye dönüştürmez. –

+1

Heh, Bu satırın benim yazımın bir noktası olmadığını anladım. –

7

, sen

Encoding.GetEncoding(1252) 

kullanarak bunu yapabilirsiniz UTF8Encoding yerine. Bu kodlama, herhangi bir bilgi kaybetmeden 8 bitlik bir değer almayı ve .NET 16 bitlik bir karaktere dönüştürmeyi ve tekrar tekrar çalışmayı amaçlar.

Yukarıda açıkladığınız özel durumda, bir ikili dosyada, "üstbilgideki meta verilerle karışıklık" edemezsiniz ve karışıklık verdiğiniz verilerin uzunluğu değişmedikçe işler düzgün çalışmayabilir. Örneğin, eğer başlık

{any}{any}ABC{any}{any} 

içeriyorsa ve istediğiniz gibi çalışması gerektiğini, DEF ABC değiştirmek istiyorum. Fakat ABC'yi WXYZ'ye değiştirmek isterseniz, "C" yi takip eden byte üzerinde yazmanız gerekecek ya da (esasen) her şeyi bir byte daha sağa taşıyacaksınız. Tipik bir ikili dosyada, bu çok şeyleri berbat eder.

"ABC" ifadesinden sonraki baytlar boşluk veya boş karakterler ise, daha büyük değiştirme verilerinin yazılmasının sorun yaratmayacağı konusunda daha iyi bir şans vardır - ancak .NET dizesindeki WXYZ ile ABC'yi daha uzun süre değiştiremezsiniz. - WXYZ ile ABC'yi {whatever_follows_it} değiştirmeniz gerekir. Bunu göz önüne alarak, verileri yalnızca bayt olarak bırakmak ve yedek verileri bir defada bir bayt yazmak daha kolay olduğunu fark edebilirsiniz.

+0

Bir bayt dizisi varsa ve belirli bir dizinin tüm yinelemelerini farklı bir uzunluktaki başka bir diziyle değiştirmeyi dilerse (örneğin, {0x7E} ile birlikte tüm 0x8D, 0x5E} örneklerini değiştirin), String kullanarak dizgeye dönüştürülür .Daha sonra geri dönüşümü makul bir yaklaşım olabilir mi? Yukarıda belirtilen kodlama, her bir byte değeri 0-255'i, karşılık gelen aynı numaralı kodla değiştirir mi [kodlamanın kayıpsız olması kendi başına olmazsa]; – supercat

+0

@supercat - evet bu yaklaşım (1252 kodlamasını kullanmanız şartıyla) işe yarar. Ancak yine de mesajımda belirtilen nedenlerden dolayı çoğu ikili dosya formatıyla bunu yapamazsınız. –

+0

Eğer biri konuma duyarlı formatlar kullanıyorsa, birilerinin hareket etmemesi gereken şeyleri sağlaması gerekir. O zaman bile, "orijinal" ve "yedek" dizgiler aynı uzunluktaysa, String.Replace öğesinin kullanışlı görüneceği durumlar olur. – supercat

İlgili konular