-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStreamExtensions.cs
More file actions
140 lines (133 loc) · 5.58 KB
/
StreamExtensions.cs
File metadata and controls
140 lines (133 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace CSharpExtensions.OpenSource
{
public static class StreamExtension
{
/// <summary>
/// Saves a stream to a local path.
/// </summary>
/// <param name="stream">The stream to save.</param>
/// <param name="filePath">The path to write into. If a file already exists there, it will be overwritten.</param>
public static void Save(this Stream stream, string filePath, bool seekToStart = false)
{
if (seekToStart)
{
stream.Seek(0, SeekOrigin.Begin);
}
// Define buffer and buffer size
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int bytesRead = 0;
// Read from response and write to file
FileStream fileStream = File.Create(filePath);
while ((bytesRead = stream.Read(buffer, 0, bufferSize)) != 0)
{
fileStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
public static string GetBase64SData(this MemoryStream? stream)
{
if (stream == null) return string.Empty;
stream.Seek(0, SeekOrigin.Begin);
return Convert.ToBase64String(stream.ToArray());
}
public static void DisposeNullable(this MemoryStream? stream)
{
if (stream == null) return;
stream.Dispose();
}
public static async Task<MemoryStream?> CopyToMemoryStream(this Stream? stream)
{
if (stream == null) { return null; }
var memStream = new MemoryStream();
await stream.CopyToAsync(memStream);
memStream.Seek(0, SeekOrigin.Begin);
return memStream;
}
public static async Task<string?> GetAllTextAsync(this Stream? stream)
{
if (stream == null) { return null; }
stream.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(stream);
var text = await reader.ReadToEndAsync();
return text;
}
public static async IAsyncEnumerable<string> StreamFileLineByLine(this StreamReader? stream)
{
if (stream == null) { yield break; }
string? readText;
while ((readText = await stream.ReadLineAsync()) != null)
{
yield return readText;
}
}
public static async IAsyncEnumerable<byte[]> StreamFileLineByLine2(this StreamReader? stream)
{
if (stream == null) { yield break; }
var bytes = new List<byte>();
int currentByte;
while ((currentByte = stream.Read()) != -1)
{
if (currentByte == '\n' || currentByte == '\r')
{
if (bytes.Count > 0) { yield return bytes.ToArray(); }
bytes.Clear();
continue;
}
bytes.Add((byte)currentByte);
}
if (bytes.Count > 0) { yield return bytes.ToArray(); }
await Task.CompletedTask;
}
public static IAsyncEnumerable<string> StreamFileLineByLineUsingRegex(this StreamReader? stream) => StreamFileByRegex(stream, new Regex(@"[\n\r]+"));
public static async IAsyncEnumerable<string> StreamFileByRegex(this StreamReader? stream, Regex regex, int bufferSize = 4096)
{
if (stream == null) { yield break; }
var sb = new StringBuilder();
var buffer = new char[bufferSize];
int currentPos;
while (!stream.EndOfStream)
{
currentPos = stream.Read(buffer, 0, bufferSize);
sb.Append(buffer, 0, currentPos);
var lines = regex.Split(sb.ToString());
for (int i = 0; i < lines.Length - 2; i++)
{
yield return lines[i];
}
sb = new StringBuilder(lines[lines.Length - 1]);
}
if (sb.Length > 0)
{
yield return sb.ToString();
}
await Task.CompletedTask;
}
public static async Task<Encoding?> GetEncodingByBom(this Stream stream)
{
using var reader = new StreamReader(stream);
var bom = new char[4];
await reader.ReadBlockAsync(bom, 0, 4);
Encoding? encodingFromBom = null;
// Analyze the BOM
if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) { encodingFromBom = Encoding.UTF7; }
else if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) { encodingFromBom = Encoding.UTF8; }
else if (bom[0] == 0xff && bom[1] == 0xfe && bom[2] == 0 && bom[3] == 0) { encodingFromBom = Encoding.UTF32; } //UTF-32LE
else if (bom[0] == 0xff && bom[1] == 0xfe) { encodingFromBom = Encoding.Unicode; } //UTF-16LE
else if (bom[0] == 0xfe && bom[1] == 0xff) { encodingFromBom = Encoding.BigEndianUnicode; } //UTF-16BE
else if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) { encodingFromBom = new UTF32Encoding(true, true); } //UTF-32BE
if (encodingFromBom != null)
{
encodingFromBom.DecoderFallback = DecoderFallback.ExceptionFallback;
encodingFromBom.EncoderFallback = EncoderFallback.ExceptionFallback;
}
return encodingFromBom;
}
}
}