У меня есть> 4 ГБ StorageFile, и я хочу преобразовать его в строку base64 и сохранить строку в другом StorageFile.
У меня есть IBuffer для чтения файла:
Dim tempFolder As StorageFolder = ApplicationData.Current.LocalFolder
Dim ftemp As StorageFile = Await tempFolder.TryGetItemAsync(filename)
Dim ibuf As IBuffer = Await FileIO.ReadBufferAsync(ftemp)
Dim b64list As New List(Of String)
Dim b64string As String = String.Empty
Dim countins As Long = 0
Dim byt As Byte() = {}
If ibuf.Length > 500000000 Then
While ibuf.Length - countins > 500000000
byt = ibuf.ToArray(countins, 500000000) 'when countins exceeds 2 Gb, i get overflowexception: Arithmetic operation resulted in an overflow
Dim b1 As String = Convert.ToBase64String(byt, 0, 500000000)
b64list.Add(b1)
countins = countins + 500000000
End While
byt = ibuf.ToArray(countins, ibuf.Length - countins)
Dim b2 As String = Convert.ToBase64String(byt, countins, ibuf.Length - countins)
b64list.Add(b2)
else
b64string = Convert.ToBase64String(ibuf.ToArray())
End If
Поскольку ограничение размера объекта Byte () составляет около 2 ГБ, я попытался разделить байты, хранящиеся в массиве буферов, на другие меньшие байты и преобразовать его в строку base64, затем добавить строку в список строк и записать строку base64 в файл по списку строк. Проблема заключается в том, что смещение байтов для чтения и преобразования превышает 2 ГБ (см. Комментарии в коде!).
есть ли способ прочитать байты от 2 ГБ и выше, содержащиеся в ibuffer?
Большое спасибо!
Редактировать: Решение Нико Чжу идеально! Большое спасибо. Это именно то, что я искал. Я попытался с файлами около 6 ГБ, и, кажется, он отлично работает, занимая в среднем 7 ГБ оперативной памяти до конечной sh операции. Для версии x86 я установил ограничение в 2 Гб для открываемых файлов, это не проблема.
Я вставляю свою версию кода vb. net для сообщества vb. net (проверено до 6 Гб):
Dim BufferList As List(Of IBuffer) = New List(Of IBuffer)()
Dim lclFolder As StorageFolder = ApplicationData.Current.LocalFolder
Dim ftemp As StorageFile = Await lclFolder.TryGetItemAsync(filename)
Dim stredam = Await ftemp.OpenAsync(FileAccessMode.Read)
Dim size As ULong = stredam.Size
Dim splLength As UInteger = 1024 * 1024 * 128
Dim splCount = size / splLength
Dim res As IBuffer = Nothing
If size < splLength Then
res = Await FileIO.ReadBufferAsync(ftemp.generalfileselectedsmp)
Else
Dim splitCount = size / splLength
For i As Integer = 0 To CInt(splitCount) - 1
Dim postition = i * splLength
Using inputStream = stredam.GetInputStreamAt(CULng(postition))
Using dataReader = New Windows.Storage.Streams.DataReader(inputStream)
Dim numBytesLoaded As UInteger = Await dataReader.LoadAsync(splLength)
Dim buffder = dataReader.ReadBuffer(numBytesLoaded)
BufferList.Add(buffder)
End Using
End Using
Next
Dim leftLength = size Mod splLength
Using inputstream As IInputStream = stredam.GetInputStreamAt(splitCount * splLength)
Using dataReader As New DataReader(inputstream)
Dim numBytesLoaded As UInteger = Await dataReader.LoadAsync(CUInt(leftLength))
Dim leftBuffer = dataReader.ReadBuffer(numBytesLoaded)
BufferList.Add(leftBuffer)
End Using
End Using
Dim nnb As Long = 0
Dim tempFolder As StorageFolder = ApplicationData.Current.TemporaryFolder
Dim ftempdest As StorageFile = Await tempFolder.CreateFileAsync("tmpxencrxx0212", CreationCollisionOption.ReplaceExisting)
For Each ibb As IBuffer In BufferList
If ibb.Length > 0 Then
Await FileIO.AppendTextAsync(ftempdest, Convert.ToBase64String(ibb.ToArray()))
nnb = nnb + 1
End If
Next