在C#中用块编码Base64字符串

时间:2014-08-13 05:49:31

标签: c# base64

我有一些文件,我将它保存在独立存储中,如何使用块将隔离流转换为Base64,如果我将流直接转换为base64,则base64变得太长,并且visual studio停止工作。那么如何使用块呢?请参阅下面的代码:

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);

3 个答案:

答案 0 :(得分:1)

我仍然不是100%关于原因,但我建议看一下类似的answer

我正在使用Web服务,我不记得需要长时间使用base64。上次我这样做是为了一个与不同的应用程序交谈的php ...你确定你需要这样做吗?


示例(使用Andrej代码)。 此案例工作,但是:在代码之后阅读警告

// 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);

以上作品。但是如果你将块大小更改为不能给你精确的Base64位(例如5而不是6),你会得到一个像SGVsbG8=IHdvcmw=ZCEAAAA=这样的字符串,然后是异常:

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... 

因此,为什么我建议玩你的输入:)

答案 1 :(得分:1)

尝试使用预定义的块大小,并按数据块读取文件。然后,您可以使用每个块中的数据并使用它。如果你需要将整个文件发布为Base64,那么通过块读取它不会改变它太长的事实,如果这是问题。

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
}

编辑:我已经在您的场景中对此进行了测试,请阅读使用块安装默认窗口时获得的Wildlife视频,并将其写入带有字节的文件,并使用Base64编码的字符串之类你正在做,两个测试都没问题,我可以在两种情况下都没有问题地播放视频,所以阅读方法不应该是这里的问题。我提供了用于测试的方法。如果问题仍然存在,请尝试上传一个小文件,并验证发送的内容是否与您的网络服务获取和保存的内容相匹配。我认为这个问题可能就是我在下面的评论中所描述的,暗示C#和Java对待Base64有点不同。

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");

答案 2 :(得分:0)