none
Работа с Base64 RRS feed

  • Вопрос

  • Такая проблемка.. передаю файл блоками по 4096 байт, переводя в строку с помощью Base64. Но когда файл передан, получаем на выходе больше байт чем положено )) 

                Dim fs As FileStream
                Dispatcher.Invoke(Sub() fs = New FileStream(Tb.Text, FileMode.Open, FileAccess.Read))
                Dim b(1024) As Byte
    
                Do While fs.Read(b, 0, b.Length) > 0
                    'Переводим строку в массив байт
                    Dim tmps As String = System.Convert.ToBase64String(b, Base64FormattingOptions.InsertLineBreaks)
                    Dim tmpb = Convert.FromBase64String(tmps)
    
                    Dispatcher.Invoke(Sub() FileIO.FileSystem.WriteAllBytes(My.Computer.FileSystem.CurrentDirectory & "\" & tname.Text, tmpb, True))
                Loop
                Dispatcher.Invoke(Sub() tblock.Text = "ОК ")
                fs.Close()
    Чем меньше блоки, тем меньше будет увеличение выходного файла. Может проблема в Base64FormattingOptions? Можно конвертировать в строку и обратно без увеличения размера файла? Иначе как проверить файл на сервере, если новый файл не соответствует размерам )))

    4 февраля 2015 г. 9:56

Ответы

  • Добрый день.

    Вы преобразуете весь массив байт в строку. А в последнем сообщении может оказаться заполнены не все символы. Вам для преобразования необходимо воспользоваться вот этой перегрузкой. При чтении из потока, результат вызова метода Read сохраняете в переменную и передаете ее в метод ToBase64String.

    • Помечено в качестве ответа Siompc 4 февраля 2015 г. 10:58
    4 февраля 2015 г. 10:08
    Отвечающий

Все ответы

  • Добрый день.

    Вы преобразуете весь массив байт в строку. А в последнем сообщении может оказаться заполнены не все символы. Вам для преобразования необходимо воспользоваться вот этой перегрузкой. При чтении из потока, результат вызова метода Read сохраняете в переменную и передаете ее в метод ToBase64String.

    • Помечено в качестве ответа Siompc 4 февраля 2015 г. 10:58
    4 февраля 2015 г. 10:08
    Отвечающий
  • А в данном примере данные разве не сохраняются в переменную d? Вот такой вариант тоже не прошел... 

    Dim tmpEnd As Integer
                Dispatcher.Invoke(Sub() tmpEnd = CInt(Int(FileIO.FileSystem.GetFileInfo(Tb.Text).Length / 4096)))
    
                Dim tmp As Integer = 1
                Dim fs As FileStream
                Dispatcher.Invoke(Sub() fs = New FileStream(Tb.Text, FileMode.Open, FileAccess.Read))
                Dim b(4096) As Byte
    
                Do While fs.Read(b, 0, b.Length) > 0
                    Dim tmps As String
                    If tmp = tmpEnd Then
                        Dispatcher.Invoke(Sub() tmps = System.Convert.ToBase64String(b, 0, CInt(FileIO.FileSystem.GetFileInfo(Tb.Text).Length - tmpEnd * 4096)))
                    Else
                        tmps = System.Convert.ToBase64String(b)
                    End If
                    'Переводим строку в массив байт
                    Dim tmpb = Convert.FromBase64String(tmps)
    
                    Dispatcher.Invoke(Sub() FileIO.FileSystem.WriteAllBytes(My.Computer.FileSystem.CurrentDirectory & "\" & tname.Text, tmpb, True))
                    tmp += 1
                    Dispatcher.Invoke(Sub() tblock.Text = CStr(tmp))
                Loop
                Dispatcher.Invoke(Sub() tblock.Text = "ОК ")
                fs.Close()
    Здесь высчитываем номер последнего блока, и добавляем в строку только то количество байт, сколько осталось. Все равно не тот размер выходит )) На 100 с лишним байт больше. Уже хоть не 2000 :))

    4 февраля 2015 г. 10:50
  • Не усложняйте. Метод Read возвращает количество байтов. Именно их сохраняйте в переменную. И именно такое количество байт преобразуйте.

    4 февраля 2015 г. 10:52
    Отвечающий
  • Спасибо большое! :)
    4 февраля 2015 г. 10:58
  • Пожалуйста. Будут вопросы, обращайтесь, постараемся помочь.

    4 февраля 2015 г. 10:59
    Отвечающий