Получить строку base64 из большого StorageFile и сохранить ее в другом StorageFile - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть> 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

1 Ответ

1 голос
/ 24 апреля 2020

есть ли способ прочитать байты от 2 ГБ и выше, содержащиеся в ibuffer?

Для ваших требований мы предлагаем вам разрезать большой файл на кусочки и использовать список IBuffer хранить каждый бланк. Обратите внимание, что вам нужно установить целевую платформу приложения на x64, которая имеет достаточно памяти для хранения таких буферов.

private List<IBuffer> BufferList = new List<IBuffer>();

var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".zip");

Windows.Storage.StorageFile sampleFile = await picker.PickSingleFileAsync();
var stredam = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
ulong size = stredam.Size;
uint splLength = 1024 * 1024 * 128;
var splCount = size / splLength;

if (size < splLength)
{
  var res = FileIO.ReadBufferAsync(sampleFile);
}
else
{
    var splitCount = size / splLength;
    for (int i = 0; i < (int)splitCount; i++)
    {
        var postition = i * splLength;
        using (var inputStream = stredam.GetInputStreamAt((ulong)postition))
        {
            using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream))
            {
                uint numBytesLoaded = await dataReader.LoadAsync(splLength);
                var buffder = dataReader.ReadBuffer(numBytesLoaded);
                BufferList.Add(buffder);
            }
        }


    }
    var leftLength = size % splLength;
    using (var inputStream = stredam.GetInputStreamAt(splitCount * splLength))
    {
        using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream))
        {
            uint numBytesLoaded = await dataReader.LoadAsync((uint)leftLength);
            var leftBuffer = dataReader.ReadBuffer(numBytesLoaded);
            BufferList.Add(leftBuffer);
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...