Jak wygenerować strumień z ciągu znaków?

Muszę napisać test jednostkowy dla metody, która pobiera strumień pochodzący z pliku tekstowego. Chciałbym zrobić coś takiego:

Stream s = GenerateStreamFromString("a,b \n c,d");
Author: Peter Mortensen, 2009-12-10

12 answers

public static Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

Nie zapomnij użyć używając:

using (var stream = GenerateStreamFromString("a,b \n c,d"))
{
    // ... Do stuff to stream
}

O tym, że StreamWriter nie są usuwane. StreamWriter jest tylko owijarką wokół strumienia bazowego i nie używa żadnych zasobów, które należy zutylizować. Metoda Dispose zamknie podstawową Stream, do której StreamWriter pisze. W tym przypadku jest to MemoryStream chcemy powrócić.

W. NET 4.5 jest teraz przeciążenie StreamWriter, które utrzymuje otwarty strumień bazowy po usunięciu Writera, ale ten kod robi to samo i działa również z innymi wersjami.NET.

Zobacz Czy Jest jakiś sposób, aby zamknąć StreamWriter bez zamykania jego BaseStream?

 1022
Author: Cameron MacFarland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-14 19:36:26

Inne rozwiązanie:

public static MemoryStream GenerateStreamFromString(string value)
{
    return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
 801
Author: joelnet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-26 19:23:00

Dodaj to do statycznej klasy użytkowej string:

public static Stream ToStream(this string str)
{
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(str);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

To dodaje funkcję rozszerzenia, więc możesz po prostu:

using (var stringStream = "My string".ToStream())
{
    // use stringStream
}
 110
Author: Josh G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-18 14:25:37
public Stream GenerateStreamFromString(string s)
{
    return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
 54
Author: Warlock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-03 18:19:28

Użyj klasy MemoryStream, wywołującej Encoding.GetBytes, aby najpierw zamienić łańcuch znaków w tablicę bajtów.

Czy następnie potrzebujesz TextReader w strumieniu? Jeśli tak, możesz podać StringReader bezpośrednio i ominąć kroki MemoryStream i Encoding.

 26
Author: Tim Robinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-10 08:17:31

Użyłem takiej kombinacji odpowiedzi:

public static Stream ToStream(this string str, Encoding enc = null)
{
    enc = enc ?? Encoding.UTF8;
    return new MemoryStream(enc.GetBytes(str ?? ""));
}

A potem używam go w ten sposób:

String someStr="This is a Test";
Encoding enc = getEncodingFromSomeWhere();
using (Stream stream = someStr.ToStream(enc))
{
    // Do something with the stream....
}
 25
Author: Robocide,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-22 22:08:02

Zmodernizowana i nieco zmodyfikowana wersja metod rozszerzenia dla ToStream:

public static Stream ToStream(this string value) => ToStream(value, Encoding.UTF8);

public static Stream ToStream(this string value, Encoding encoding) 
                          => new MemoryStream(encoding.GetBytes(value ?? string.Empty));

Modyfikacja zgodnie z sugestią w komentarzu @ Palec odpowiedzi @ Shaun Bowe.

 20
Author: Nick N.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-14 10:05:28

Używamy metod rozszerzenia wymienionych poniżej. Myślę, że powinieneś skłonić dewelopera do podjęcia decyzji co do kodowania, więc jest mniej magii.

public static class StringExtensions {

    public static Stream ToStream(this string s) {
        return s.ToStream(Encoding.UTF8);
    }

    public static Stream ToStream(this string s, Encoding encoding) {
        return new MemoryStream(encoding.GetBytes(s ?? ""));
    }
}
 14
Author: Shaun Bowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-22 22:08:53

Proszę bardzo:

private Stream GenerateStreamFromString(String p)
{
    Byte[] bytes = UTF8Encoding.GetBytes(p);
    MemoryStream strm = new MemoryStream();
    strm.Write(bytes, 0, bytes.Length);
    return strm;
}
 10
Author: cjk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-10 08:27:25

Myślę, że możesz skorzystać z MemoryStream . Możesz wypełnić go bajtami łańcuchowymi, które uzyskasz za pomocą metody GetBytes klasy kodowania .

 8
Author: Konamiman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-10 08:18:00

Jeśli chcesz zmienić kodowanie, Głosuję na rozwiązanie @ ShaunBowe. Ale każda odpowiedź tutaj Kopiuje cały łańcuch w pamięci przynajmniej raz. Odpowiedzi z ToCharArray + BlockCopy combo zrób to dwa razy.

Jeśli to ma znaczenie tutaj jest prosty Stream wrapper dla surowego ciągu UTF-16. Jeśli używany z StreamReader Wybierz Encoding.Unicode dla niego:

public class StringStream : Stream
{
    private readonly string str;

    public override bool CanRead => true;
    public override bool CanSeek => true;
    public override bool CanWrite => false;
    public override long Length => str.Length * 2;
    public override long Position { get; set; } // TODO: bounds check

    public StringStream(string s) => str = s ?? throw new ArgumentNullException(nameof(s));

    public override long Seek(long offset, SeekOrigin origin)
    {
        switch (origin)
        {
            case SeekOrigin.Begin:
                Position = offset;
                break;
            case SeekOrigin.Current:
                Position += offset;
                break;
            case SeekOrigin.End:
                Position = Length - offset;
                break;
        }

        return Position;
    }

    private byte this[int i] => (i & 1) == 0 ? (byte)(str[i / 2] & 0xFF) : (byte)(str[i / 2] >> 8);

    public override int Read(byte[] buffer, int offset, int count)
    {
        // TODO: bounds check
        var len = Math.Min(count, Length - Position);
        for (int i = 0; i < len; i++)
            buffer[offset++] = this[(int)(Position++)];
        return (int)len;
    }

    public override int ReadByte() => Position >= Length ? -1 : this[(int)Position++];
    public override void Flush() { }
    public override void SetLength(long value) => throw new NotSupportedException();
    public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
    public override string ToString() => str; // ;)     
}

I tutaj jest bardziej kompletnym rozwiązaniem z niezbędnymi sprawdzeniami związanymi (pochodzącymi z MemoryStream więc ma metody ToArray i WriteTo jako cóż).

 5
Author: György Kőszeg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-18 18:50:18

Dobra kombinacja rozszerzeń łańcuchów:

public static byte[] GetBytes(this string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

public static Stream ToStream(this string str)
{
    Stream StringStream = new MemoryStream();
    StringStream.Read(str.GetBytes(), 0, str.Length);
    return StringStream;
}
 -2
Author: MarkWalls,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-22 22:07:11