来自 MemoryStream 的 StreamReader
StreamReader from MemoryStream
我正在从 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 = ms.ToArray();
}
如何简单地通过字符串读取解码后的文件?
例如,类似于我们如何从 HttpWebResponse
流中读取文件的方式:
using (StreamReader input = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1251), true))
{
while (!input.EndOfStream)
{
string row = input.ReadLine();
}
}
不用转数组,直接把内存流位置重置为0然后把内存流传给reader读到结束
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 格式可以包含换行符 inside 字段,几乎所有从电子表格文件写入 CSV 的东西(如 MS Excel)都支持此功能。要支持这一点,line-by-line-reading 方法太简单了。 .Net 框架包含一个本机 CSV reader,虽然在 Microsoft.VisualBasic
classes 中隐藏得很好。但是,由于 .Net 是一个框架,因此没有什么可以阻止您添加引用并在 C# 中使用它。 class 是 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;
}
我正在从 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 = ms.ToArray();
}
如何简单地通过字符串读取解码后的文件?
例如,类似于我们如何从 HttpWebResponse
流中读取文件的方式:
using (StreamReader input = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1251), true))
{
while (!input.EndOfStream)
{
string row = input.ReadLine();
}
}
不用转数组,直接把内存流位置重置为0然后把内存流传给reader读到结束
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 格式可以包含换行符 inside 字段,几乎所有从电子表格文件写入 CSV 的东西(如 MS Excel)都支持此功能。要支持这一点,line-by-line-reading 方法太简单了。 .Net 框架包含一个本机 CSV reader,虽然在 Microsoft.VisualBasic
classes 中隐藏得很好。但是,由于 .Net 是一个框架,因此没有什么可以阻止您添加引用并在 C# 中使用它。 class 是 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;
}