我有一个Android移动应用程序,具有设置个人资料图片的功能。
我将包含图像路径的变量发送到执行以下操作的方法:
string imagePath = _ProfilePicture.GetTag (Resource.String.profile_picture_path).ToString ();
byte[] imageBytes = System.IO.File.ReadAllBytes(imagePath);
Stream imageStream = new MemoryStream(imageBytes);
在这段代码之后,我将imageStream变量发送到位于WCF服务上的UploadUserProfilePicture(imageStream);
目前它只发送流,但因为我们无法发送包含扩展名的其他参数。我们将所有图像保存为png。然而,我找到了一个库,需要将流解析为字节,然后根据文件类型可以检索的字节。
然而,当我尝试使用相同的流将文件写入服务器上的位置时,位置位于末尾,因此创建的文件始终为0字节。
我试过了: 在另一个方法中转换为Bytes并仅返回fileType,但原始位置仍然在结尾。 CopyTo函数给了我相同的结果。 我尝试使用Seek函数并将其位置设置为零,但是我得到了NotSupportedException。
我也尝试了这个:
string content;
var reader = new StreamReader(image);
content = reader.ReadToEnd();
image.Dispose();
image = new MemoryStream(Encoding.UTF8.GetBytes(content));
^这似乎会破坏流,因为我无法获取FileType,也无法将其写入上述位置。
我还看过:How to read a Stream and reset its position to zero even if stream.CanSeek == false
这是WCF服务上的方法:
public Result UploadUserProfilePicture(Stream image)
{
try
{
FileType fileType = CommonMethods.ReadToEnd(image).GetFileType();
Guid guid = Guid.NewGuid();
string imageName = guid.ToString() + "." + fileType.Extension;
var buf = new byte[1024];
var path = Path.Combine(@"C:\" + imageName);
int len = 0;
using (var fs = File.Create(path))
{
while ((len = image.Read(buf, 0, buf.Length)) > 0)
{
fs.Write(buf, 0, len);
}
}
return new Result
{
Success = true,
Message = imageName
};
}
catch(Exception ex)
{
return new Result
{
Success = false,
Message = ex.ToString()
};
}
使用的图书馆链接:https://github.com/Muraad/Mime-Detective CommonMethods.ReadToEnd(image)方法可以在这里找到:How to convert an Stream into a byte[] in C#?作为问题的答案
我希望这是关于我的问题的足够信息。
答案 0 :(得分:1)
在服务器端,您收到来自WCF的不支持搜索操作的流。但是,您可以将流读取到内存,因为GetFileType
方法需要一个字节数组作为输入参数。您可以使用File.WriteAllBytes方法以非常简单的方式将数组的字节写入磁盘,而不是再次访问原始流:
public Result UploadUserProfilePicture(Stream image)
{
try
{
// Store bytes in a variable
var bytes = CommonMethods.ReadToEnd(image);
FileType fileType = bytes.GetFileType();
Guid guid = Guid.NewGuid();
string imageName = guid.ToString() + "." + fileType.Extension;
var path = Path.Combine(@"C:\" + imageName);
File.WriteAllBytes(path, bytes);
return new Result
{
Success = true,
Message = imageName
};
}
catch(Exception ex)
{
return new Result
{
Success = false,
Message = ex.ToString()
};
}
}
请注意,这意味着您可能会在内存中存储大量字节,就像您之前所做的那样。如果您可以在不将所有字节读入内存的情况下使用流更好,那么寻找可以处理流的GetFileType
方法的替代方案是非常值得的。然后,您可以先将映像保存到临时文件,然后打开新的FileStream以发现正确的文件类型,以便重命名该文件。