【问题标题】:BinaryReader.ReadBytes returning junk when converted to stringBinaryReader.ReadBytes 转换为字符串时返回垃圾
【发布时间】:2013-07-01 12:26:38
【问题描述】:

如果我试图解释为什么我需要做我想做的事情,这将需要很长时间,但基本上是这样的:我有 FileUpload 控件供用户选择 Jpeg 文件,我进行上传并之后我想将该文件转换为字节并将其用作 Image 控件的源。

我的代码是这个:

string fileName = Server.MapPath("~/TempImages") + @"\foto.jpg";
fileUpload1.SaveAs(fileName);

System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
long byteLength = new System.IO.FileInfo(fileName).Length;
byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
fs.Close();
fs.Dispose();

string valor = System.Text.Encoding.UTF8.GetString(buffer);
img.ImageUrl = "data:image/jpg;base64," + valor;

字节数组看起来不错,但是当我将它转换为字符串时,它充满了无法识别的字符,我有另一个页面,我在其中做同样的事情,但我没有从文件中获取字节,而是从 MySql 数据库中获取它并且使用相同的System.Text.Encoding.UTF8.GetString,它可以正常工作。

更新 如所问,这是我从 MySql 数据库中检索时使用的代码:

DataView dv = (DataView)SqlDataSource3.Select(DataSourceSelectArguments.Empty);
byte[] buffer = (byte[])dv.Table.Rows[0]["BIN_FOTO"];
string valor = System.Text.Encoding.UTF8.GetString(buffer);
img.ImageUrl = "data:image/jpg;base64," + valor;

这个SqlDataSource3的select是一个简单的Select BIN_FOTO from temp_image。我将此值从网络摄像头捕获 WPF 程序存储在数据库中,用于转换网络摄像头捕获的图像的代码是:

    private string ImageToBase64String(System.Drawing.Image imageData, ImageFormat format)
    {
        string base64;
        MemoryStream memory = new MemoryStream();
        imageData.Save(memory, format);
        base64 = System.Convert.ToBase64String(memory.ToArray());
        memory.Close();
        memory.Dispose();

        return base64;
    }

然后我将base64 变量保存到数据库中。

希望这能澄清我的问题

【问题讨论】:

  • 将图像字节数组解释为字符串不会给你任何可理解的东西。看看您的图像如何存储在 MySql 中会很有趣。可能在保存或检索过程中发生了一些转换。
  • 更新它以显示我如何保存到 MySql。

标签: asp.net bytearray filestream binaryreader


【解决方案1】:

所以你想读取图像文件并转换为base 64。读取代码后,执行以下操作:

string valor = Convert.ToBase64String(buffer);

您的原始代码存在缺陷,因为您使用以下代码行将图像以字节形式保存到文件中:

fileUpload1.SaveAs(fileName);

那不是保存为base64,所以你必须在阅读后将其转换为base 64。您的 MySql 读取有效,因为数据在保存之前已转换为 base64。

顺便说一句,这段代码中不需要BinaryReader

System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
long byteLength = new System.IO.FileInfo(fileName).Length;
byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
fs.Close();
fs.Dispose();

你可以这样写:

byte[] buffer;
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)
{
    long byteLength = fs.Length;
    buffer = new byte[byteLength];
    int bytesRead = fs.Read(buffer, 0, byteLength);
    // optional error check to see that you got all the bytes
    if (bytesRead != byteLength)
    {
        // handle error
    }
}
string valor = Convert.ToBase64String(buffer);

【讨论】:

  • 是的,我在您回答之前几秒钟就发现了这一点,无论如何,谢谢,但是我的第一种方法有什么问题?当我从数据库中获取字节时它可以工作,但是当它们来自文件时它停止工作。
  • 感谢您的解释!
【解决方案2】:

我发现了问题,查看了我用来将图像转换为 Base64String 的 WPF 代码。我刚刚创建了相同的函数ImageToBase64String,现在它可以工作了:

        string fileName = Server.MapPath("~/TempImages") + @"\foto.jpg";
        fileUpload1.SaveAs(fileName);

        System.Drawing.Image teste = System.Drawing.Image.FromFile(fileName);

        string valor = ImageToBase64String(teste, System.Drawing.Imaging.ImageFormat.Jpeg);

        //System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
        //System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
        //long byteLength = new System.IO.FileInfo(fileName).Length;
        //byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
        //buffer = File.ReadAllBytes(fileName);
        //fs.Close();
        //fs.Dispose();

        //string valor = System.Text.Encoding.UTF8.GetString(buffer);
        img.ImageUrl = "data:image/jpg;base64," + valor;

但我仍然不知道我之前的代码有什么问题,有人可以澄清一下吗?

【讨论】:

    【解决方案3】:

    这个解决方案对我有用:

    System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
    //Add this--------------------
    fs.Seek(0, SeekOrigin.Begin);
    //----------------------------
    long byteLength = new System.IO.FileInfo(fileName).Length;
    byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
    

    只需添加突出显示的行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-30
      • 2023-04-07
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多