C# 来自MemoryStream的StreamReader
我正在从base64字符串解码csv文件:C# 来自MemoryStream的StreamReader,c#,stream,.net-4.6,C#,Stream,.net 4.6,我正在从base64字符串解码csv文件: byte[] input; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write)) using (var tr = new StreamWriter(cs)) { tr.Write(data); tr.Flush(); input = m
byte[] input;
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write))
using (var tr = new StreamWriter(cs))
{
tr.Write(data);
tr.Flush();
input = ms.ToArray();
}
如何简单地按字符串读取解码文件?
例如,类似于从HttpWebResponse
stream读取文件的方式:
using (StreamReader input = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1251), true))
{
while (!input.EndOfStream)
{
string row = input.ReadLine();
}
}
不必费心转换到数组,只需将内存流位置重置为0,然后将内存流传递给读卡器,然后读取到末尾
using (var ms = new MemoryStream()) {
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write)) {
using (var tr = new StreamWriter(cs)) {
tr.Write(data);
tr.Flush();
ms.Position = 0;
using (var reader = new StreamReader(ms, Encoding.GetEncoding(1251), true)) {
string csv = reader.ReadToEnd();
//OR
//while (!reader.EndOfStream) {
// var line = reader.ReadLine();
//}
}
}
}
}
这是另一个选择
byte[] input;
using (var ms = new MemoryStream()) {
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write)) {
using (var tr = new StreamWriter(cs)) {
tr.Write(data);
tr.Flush();
input = ms.ToArray();
}
}
}
using (var ms = new MemoryStream(input)) {
using (var reader = new StreamReader(ms, Encoding.GetEncoding(1251), true)) {
string csv = reader.ReadToEnd();
//OR
//while (!reader.EndOfStream) {
// var line = reader.ReadLine();
//}
}
}
您可以从一个数组开始初始化
MemoryStream
;然后,您不必向流写入任何内容。因为根据定义,Base64是纯ascii文本,所以只需使用ascii编码将输入字符串转换为字节
不过,如果要解析CSV,有比逐行读取文本更好的输出选项。从技术上讲,CSV格式可以在字段中包含换行符,这是一种几乎所有从电子表格文件(如MS Excel)写入CSV的内容都支持的功能。为了支持这一点,逐行阅读的方法太简单了。尽管.Net framework包含一个本机CSV阅读器,但它在Microsoft.VisualBasic
类中隐藏得相当好。但是,由于.Net是一个框架,因此没有什么可以阻止您添加引用并在C#中使用它。该类是TextFieldParser
,来自Microsoft.VisualBasic.FileIO
public static List<String[]> ParseBase64Csv(String data, Encoding encoding, Char separator, Boolean ignoreEmptyLines)
{
List<String[]> splitLines = new List<String[]>();
using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(data)))
using (FromBase64Transform tr = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
using (CryptoStream cs = new CryptoStream(ms, tr, CryptoStreamMode.Read))
using (StreamReader sr = new StreamReader(cs, encoding))
using (TextFieldParser tfp = new TextFieldParser(sr))
{
tfp.TextFieldType = FieldType.Delimited;
tfp.Delimiters = new String[] { separator.ToString() };
while (true)
{
try
{
String[] curLine = tfp.ReadFields();
if (curLine == null)
break;
if (ignoreEmptyLines && (curLine.Length == 0 || curLine.All(x => String.IsNullOrEmpty(x) || String.IsNullOrEmpty(x.Trim()))))
continue;
splitLines.Add(curLine);
}
catch (MalformedLineException mfle)
{
// do something with errors here.
}
}
}
return splitLines;
}
公共静态列表ParseBase64Csv(字符串数据、编码、字符分隔符、布尔ignoreEmptyLines)
{
列表分割线=新列表();
使用(MemoryStream ms=new MemoryStream(Encoding.ASCII.GetBytes(data)))
使用(FromBase64Transform tr=new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
使用(CryptoStream cs=新的CryptoStream(ms、tr、CryptoStreamMode.Read))
使用(StreamReader sr=新的StreamReader(cs,编码))
使用(TextFieldParser tfp=新的TextFieldParser(sr))
{
tfp.TextFieldType=FieldType.Delimited;
tfp.Delimiters=新字符串[]{separator.ToString()};
while(true)
{
尝试
{
字符串[]curLine=tfp.ReadFields();
if(curLine==null)
打破
if(ignoreEmptyLines&(curLine.Length==0 | | | curLine.All(x=>String.IsNullOrEmpty(x)| | | String.IsNullOrEmpty(x.Trim()))
继续;
拆分线。添加(卷曲线);
}
捕获(格式错误的LineException mfle)
{
//在这里做一些有错误的事情。
}
}
}
返回分割线;
}
@Nkosi将内存流传递给读者的方式正是我所要求的for@Nkosi你的解决方案是可行的,即使不是那么完美。我必须从base64字符串解析csv文件,并将数据写入数据库。从技术上讲,csv格式允许单元格内换行。如果您的输入可能来自转换后的电子表格文件,您可以查看而不是逐行读取。我一直在读取MemoryStream,然后需要从中读取,并且在我的流读取器中不断获取ReadLine()return null。当我看到你在内存流中将位置设置为0时,我会说“你一定是在开玩笑吧”。。。不能相信,它不默认从流读取器中内存流的开头读取。非常感谢你的回答!