Reputation: 888
I have some files and I am saving it in isolated storage, how do I convert isolated stream to Base64 using chunks, If I convert stream directly to base64 then, base64 becomes too long, and visual studio stopped working. So how to do using chunks? See my code below:
BinaryReader rdr = new BinaryReader(isofile);
long lng = rdr.BaseStream.Length;
int rr = Convert.ToInt32(lng);
byte[] b = rdr.ReadBytes(rr);
string str = Convert.ToBase64String(b);
Upvotes: 2
Views: 5561
Reputation: 423
I would go with https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.tobase64transform?view=netcore-3.1
I would implement this in a way like here https://gist.github.com/sebnilsson/e12a96cd07e5b044eea7bc8b7477b20d
Upvotes: 0
Reputation: 800
Try using a predefined chunk size and read the file by chunks of data. Then you can use data from each chunk and use it. If you need to post the entire file as Base64, reading it by chunks will not change the fact it is too long, if that's the problem.
int chunkSize = 1024;
string source = @"file.accdb";
BinaryReader rdr = new BinaryReader(new FileStream(source, FileMode.Open));
int streamLength = (int)rdr.BaseStream.Length;
while (rdr.BaseStream.Position < rdr.BaseStream.Length)
{
byte[] b = new byte[chunkSize];
long remaining = rdr.BaseStream.Length - rdr.BaseStream.Position;
if(remaining >= chunkSize)
{
rdr.Read(b, 0, chunkSize);
}
else
{
rdr.Read(b, 0, (int)remaining);
}
string chunkString = Convert.ToBase64String(b);
// .. do something with the chunk of data, write to a stream, etc
}
EDIT: I've tested this in your scenario, read the Wildlife video that you get with default windows installation with chunks and wrote them to a file with bytes, and also using Base64 encoded string like you are doing, both tests were OK, and I could play back the video without a problem in both cases, so the method of reading shouldn't be the problem here. I've supplied the method I used for the test. If the problem still persists, try uploading a small file and verify the sent contents match what your web service is getting and saving. I think that the problem might be what I described in the comment below, the hint that C# and Java treat Base64 a bit differently.
StringBuilder acc = new StringBuilder();
int chunkSize = 2187;
string source = @"Wildlife.wmv";
BinaryReader rdr = new BinaryReader(new FileStream(source, FileMode.Open));
while (rdr.BaseStream.Position < rdr.BaseStream.Length)
{
byte[] b = new byte[chunkSize];
long remaining = rdr.BaseStream.Length - rdr.BaseStream.Position;
if (remaining >= chunkSize)
{
rdr.Read(b, 0, chunkSize);
}
else
{
rdr.Read(b, 0, (int)remaining);
}
acc.Append(Convert.ToBase64String(b));
}
FileStream fs = new FileStream(@"c:\dev\test.wmv", FileMode.OpenOrCreate);
fs.Write(Convert.FromBase64String(acc.ToString()),0,0);
Process.Start(@"c:\dev\test.wmv");
Upvotes: 3
Reputation: 11763
I'm still not a 100% about the why, but I would suggest looking at this answer for something similar.
I'm working with web services, and I can't remember needing to use base64 in a long time. Last time I did it was for a php one that talked to different applications ... You sure you need to do this?
Example (using Andrej code). THIS CASE WORKS , BUT : Read the warning after the code for more.
// Input
var my_string = "Hello world!";
// Get as binary
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
var input_as_binary = encoding.GetBytes(my_string);
/*
72
101
108
108
111
32
119
111
114
108
100
33
*/
// If the following is not an exact divisor, It won't work.
int chunkSize = 6;
// Create a stream and reader
Stream stream = new MemoryStream(as_binary);
BinaryReader rdr = new BinaryReader(stream);
int streamLength = (int)rdr.BaseStream.Length;
// A stub to hold the bits of Base64. This will happen on your receiving end
var sb = new StringBuilder();
// from Andrej answer, I'm just using the "streamLength" Var he defined
while (rdr.BaseStream.Position < streamLength)
{
byte[] b = new byte[chunkSize];
long remaining = streamLength - rdr.BaseStream.Position;
if(remaining >= chunkSize)
{
rdr.Read(b, 0, chunkSize);
}
else
{
rdr.Read(b, 0, (int)remaining);
}
string chunkString = Convert.ToBase64String(b).Dump("as base 64");
// Lets assume we send it and it's received on the other side
sb.Append(chunkString);
}
// This should happen on your receiving side as well
var other_side = sb.ToString(); // value => SGVsbG8gd29ybGQh
// Back into byte array
var byte_from_64 = Convert.FromBase64String(other_side);
// Back into string. Will hold "Hello World!"
var string_from_byte = encoding.GetString(byte_from_64);
The above works. But if you change the chunk size to something that doesn't give you precise Base64 bits (5 for example, instead of 6), you'll get a string like SGVsbG8=IHdvcmw=ZCEAAAA=
and then an exception:
FormatException
The input is not a valid Base-64 string as it contains a non-base 64 character
, more than two padding characters, or an illegal character among the pa...
Hence why I suggested playing around with your input :)
Upvotes: 1