2016-09-06 5 views
0

Я конвертирую файлы изображений в строки base64, чтобы хранить их в TXT-файле, а затем извлекать их и переконвертировать в изображения. При этом, я обнаружил забавный проступок от имени моего StringBuilder:Разница между новой строкой StreamWriter и новой строкой StringBuilder?

// **Example A, uses StringBuilder** 
String[] filePaths = Directory.GetFiles(folderPath, "*.*"); 
StringBuilder sb = new StringBuilder(); 

ImageConverter converter = new ImageConverter(); 
StreamWriter sw = File.CreateText(filepathBase64); 

foreach (String item in filePaths) 
{ 
    try 
    { 
     Bitmap picture = new Bitmap(item); 
     Byte[] byteArr = (Byte[])converter.ConvertTo(picture, typeof(Byte[])); 
     String base64 = Convert.ToBase64String(byteArr); 
     sb.AppendLine(base64); 
    } 
    catch { } 
} 

StreamWriter sw = File.CreateText(filepathBase64); 
sw.Write(sb); 
sw.Flush(); 
sw.Close(); 

Это создает файл .txt, содержащее множество строк в base64 и один последней пустой строке, причитающиеся .AppendLine используется с моим StringBuilder. Когда я позже прочитал эти base64 строк и конвертировать их обратно в объекты изображения, я должен быть осторожным в этой последней строке, чтобы избежать исключения, поэтому я проверяю его, как так:

//**Example A.1, checking for empty string 
listBoxbilder.Items.Clear(); 
String[] myArr = File.ReadAllLines(filepathBase64);//last item will be empty string 

foreach (String item in myArr) 
{ 
    if (item != String.Empty) //This is my validation 
    { 
     byte[] decodedFromBase64 = Convert.FromBase64String(item); 
     BitmapImage myImage = new BitmapImage(); 

     myImage.BeginInit(); 
     myImage.StreamSource = new MemoryStream(decodedFromBase64); 
     myImage.EndInit(); 

     ListBoxItem bild = new ListBoxItem(); 
     bild.Content = new System.Windows.Controls.Image() { Source = myImage }; 
     listBoxbilder.Items.Add(bild); 
    } 
} 

Теперь, если я выполните ту же задачу с немного другой сборкой, используя мой StreamWriter, чтобы написать прямо в мой файл, не потрудившись использовать StringBuilder, получившийся .txt выглядит как невооруженным глазом, но код ведет себя по-разному. Вот немного для создания файла:

//**Example B, just uses StreamWriter** 
String[] filePaths = Directory.GetFiles(folderPath, "*.*"); 
ImageConverter converter = new ImageConverter(); 
StreamWriter sw = File.CreateText(filepathBase64); 

foreach (String item in filePaths) 
{ 
    try 
    { 
     Bitmap picture = new Bitmap(item); 
     Byte[] byteArr = (Byte[])converter.ConvertTo(picture, typeof(Byte[])); 
     String base64 = Convert.ToBase64String(byteArr); 
     sw.WriteLine(base64); 
    } 
    catch{ } 
}  

sw.Flush(); 
sw.Close(); 

Я до сих пор есть пустая строка в конце моего файла, но когда я прочитал этот файл в массив с помощью File.ReadAllLines, я не получаю массив, где последняя позиция - пустая строка. Как идет? Теперь я могу использовать код без проверки на пустота, вот так:

//**Example B.1, no checks 
listBoxbilder.Items.Clear(); 
String[] myArr = File.ReadAllLines(filepathBase64); 
foreach (String item in myArr) 
{ 
    byte[] decodedFromBase64 = Convert.FromBase64String(item); 
    BitmapImage myImage = new BitmapImage(); 
    myImage.BeginInit(); 
    myImage.StreamSource = new MemoryStream(decodedFromBase64); 
    myImage.EndInit(); 
    ListBoxItem bild = new ListBoxItem(); 
    bild.Content = new System.Windows.Controls.Image() { Source = myImage }; 
    listBoxbilder.Items.Add(bild); 
} 

Я не получаю исключение, так как результирующий массив из File.ReadAllLines не имеет позиций, содержащие пустую строку, однако .txt источник выглядит одинаково, имея пустую строку в самом конце. В чем причина этого различного поведения?

+2

Я бы * начал *, удалив эти пустые блоки блокировки. Затем выясните, что такое * фактические * различия в файле. Напишите небольшое консольное приложение для записи в два файла, по одному в каждом. Нет необходимости в base64, нет необходимости в каких-либо интерфейсах и т. Д. ... просто напишите в файл. Сравните эти файлы очень тщательно, например. с редактором двоичных файлов. –

+0

Каково значение _filepathBase64_, это должно быть имя файла, но таким образом вы могли бы поместить байты более чем одного файла в один файл. Это верно? – Steve

+0

Для сравнения я сначала использовал готовые утилиты, такие как hexdump (GNU), и сравнил выходные данные для двух файлов с помощью инструмента diff. – grenix

ответ

0

Эффект исчез. Я не знаю, что такое черная магия, космическое излучение или простой надзор, что моя часть вызвала это неустойчивое поведение раньше, этого больше не происходит. Полученные файлы имеют одинаковое количество байтов и идентичных контрольных сумм, и они ведут себя одинаково, когда я использую их в своей программе.

+0

должно быть какое-то недоразумение, бывает, что помнить, что при программировании это означает, что если вы добавите 1 к 1, вы ВСЕГДА получите 2, если вы получаете что-нибудь другое, то что логично, его вы, кто что-то делает не так, нет магия, все оправдано до последних бит. Если вы придерживаетесь этой веры близко к сердцу, вы всегда поймаете проблему быстро, вместо того, чтобы думать, что происходит какая-то сверхъестественная магия. – user734028

+0

Должен ли я использовать больше смайликов в будущем, когда я беззаботно отношусь к своим собственным недостаткам? ;-) В любом случае, спасибо за ваш комментарий. Это ценно. – HerrMetik

Смежные вопросы