Vb.net 从一个大的StorageFile中获取base64字符串并将其存储在另一个StorageFile中

Vb.net 从一个大的StorageFile中获取base64字符串并将其存储在另一个StorageFile中,vb.net,uwp,Vb.net,Uwp,我有一个大于4 GB的StorageFile,我想将其转换为base64字符串,并将该字符串存储在另一个StorageFile中 我必须让IBuffer阅读该文件: Dim tempFolder As StorageFolder = ApplicationData.Current.LocalFolder Dim ftemp As StorageFile = Await tempFolder.TryGetItemAsync(filename) Dim ibuf As IBuffer = Aw

我有一个大于4 GB的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()对象的大小限制约为2Gb,因此我尝试将存储在缓冲区数组中的字节拆分为其他较小的字节,并将其转换为base64字符串,然后将该字符串添加到字符串列表中,并按字符串列表将base64字符串写入文件中。问题是当要读取和转换的字节偏移量超过2Gb时(请参见代码中的注释!)

有没有办法读取ibuffer中包含的从2GB到更高的字节

多谢各位

编辑: Nico Zhu的解决方案是完美的!非常感谢你。 那正是我想要的。 我尝试使用大约6GB的文件,它似乎工作得很好,平均占用7GB的ram来完成操作。对于x86版本,我为文件打开设置了2GB的限制,这不是问题

我为vb.net社区粘贴我的vb.net代码版本(测试高达6Gb):

Dim BufferList As List(属于IBuffer)=新列表(属于IBuffer)()
Dim lclFolder As StorageFolder=ApplicationData.Current.LocalFolder
Dim ftemp As StorageFile=wait lclFolder.TryGetItemAsync(文件名)
Dim stredam=wait ftemp.OpenAsync(FileAccessMode.Read)
尺寸为ULong=stredam.size
尺寸长度为UInteger=1024*1024*128
尺寸splCount=尺寸/长度
Dim res As IBuffer=无
如果尺寸小于长度,则
res=等待文件IO.ReadBufferAsync(ftemp.generalfileselectedsmp)
其他的
尺寸拆分计数=尺寸/长度
对于i,整数=0到CInt(拆分计数)-1
尺寸位置=i*splLength
使用inputStream=stredam.GetInputStreamAt(CULng(position))
使用dataReader=New Windows.Storage.Streams.dataReader(inputStream)
Dim numBytesLoaded为UInteger=Wait dataReader.LoadAsync(splLength)
Dim BUFFER=dataReader.ReadBuffer(numBytesLoaded)
BufferList.Add(bufferder)
终端使用
终端使用
下一个
尺寸leftLength=尺寸Mod长度
使用inputstream作为IIInputStream=stredam.GetInputStreamAt(splitCount*splLength)
将dataReader用作新的dataReader(inputstream)
Dim numBytesLoaded为UInteger=wait dataReader.LoadAsync(CUInt(leftLength))
Dim leftBuffer=dataReader.ReadBuffer(numBytesLoaded)
添加(leftBuffer)
终端使用
终端使用
长度为0时的尺寸nnb
Dim tempFolder As StorageFolder=ApplicationData.Current.Temporary文件夹
Dim ftempdest As StorageFile=wait tempFolder.CreateFileAsync(“tmpxencrxx0212”,CreationCollisionOption.ReplaceExisting)
对于缓冲区列表中作为IBuffer的每个ibb
如果ibb.Length>0,则
等待FileIO.AppendTextAsync(ftempdest,Convert.ToBase64String(ibb.ToArray()))
nnb=nnb+1
如果结束
下一个
有没有办法读取ibuffer中包含的从2GB到更高的字节

根据您的要求,我们建议您将大文件切成片,并使用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);
        }
    }

}
private List BufferList=new List();
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尺寸=拉伸尺寸;
uint splLength=1024*1024*128;
var splCount=大小/长度;
如果(尺寸<长度)
{
var res=FileIO.ReadBufferAsync(sampleFile);
}
其他的
{
var splitCount=大小/长度;
对于(int i=0;i<(int)拆分计数;i++)
{
变量位置=i*splLength;
使用(var inputStream=stredam.GetInputStreamAt((ulong)位置))
{
使用(var dataReader=newwindows.Storage.Streams.dataReader(inputStream))
{
uint numBytesLoaded=等待dataReader.LoadAsync(splLength);
var buffder=dataReader.ReadBuffer(numBytesLoaded);
BufferList.Add(bufferder);
}
}
}
var leftLength=大小%splength;
使用(var inputStream=stredam.getinputstreeamat(splitCount*splength))
{
使用(var dataReader=newwindows.Storage.Streams.dataReader(inputStream))
{
uint numBytesLoaded=等待dataReader.LoadAsync((uint)leftLength);
var leftBuffer=dataReader.ReadBuffer(numBytesLoaded);
BufferList.Add(leftBuffer);
}
}
}

您为什么需要列表?只需读取一个8字节长的数据块,将其转换为base-64并将结果写入输出文件。在写之前不需要存储结果。完美的解决方案,这正是我所寻找的。
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);
        }
    }

}