powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Преобразование SqlDataReader в Stream
25 сообщений из 44, страница 1 из 2
Преобразование SqlDataReader в Stream
    #39247474
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
.Net Framework 2.0
Необходимо сохранить данные, полученные последовательно от нескольких SqlDataReader напрямую в шифрованный zip-архив.
Для работы с zip-файлами использую Ionic.Zip.dll:
Код: c#
1.
2.
3.
4.
5.
6.
7.
using(ZipFile zip = new ZipFile())
{
   zip.Encryption = EncryptionAlgorithm.WinZipAes256;
   zip.Password = "MyPassword";
   zip.AddEntry("data1.txt", stream1);
   zip.AddEntry("data2.txt", stream2);
}



изначально делал неумно (это приводило к OutOfMemoryException):
Код: c#
1.
2.
3.
4.
5.
SqlCommand Cmd = new SqlCommand("select [Field1],[Field2] from [Table]", Conn);
SqlDataReader reader = Cmd.ExecuteReader();
MemoryStream ms = new MemoryStream();
SqlDataReaderToStream(reader, ref ms);
reader.Close();



как реализовать запись потока напрямую в zip-файл?

p.s. реализацию процесса записи результатов SqlDataReader в поток не привожу, так как она тривиальна и сводится к формированию в заголовков полей и строк данных в юникоде с некоторым преобразованием.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247561
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Так можно, например
Код: c#
1.
2.
3.
4.
5.
                    DataTable dt = new DataTable();
                    SqlDataReader sdr = sqlCommand.ExecuteReader();
                    dt.Load(sdr);
                    MemoryStream ms = new MemoryStream();
                    dt.WriteXml(ms);
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247565
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cat2,
там большое количество данных - OutOfMemoryException
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247571
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нашел интересную ссылку , но разобраться всё равно не могу, помогите пожалуйста.
Раньше у меня работал метод SqlDataReaderToStream, но при большом количестве данных это не работает.
Код: c#
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.
static void SqlDataReaderToStream(SqlDataReader _reader, ref MemoryStream _ms)
{
   byte[] buffer = new byte[1024 * 1024]; // 1Мб
   int cnt = 0;
   string Delimiter = "\t";
   string Terminator = "\n";
   Encoding enc = Encoding.Unicode;
   _ms.Seek(0, SeekOrigin.Begin);
   // Unicode BOM FFFE
   _ms.Write(new byte[] { 0xFF, 0xFE }, 0, 2);
   //Пишем данные
   string Field = "";
   while (_reader.Read())
   {
      for (int i = 0; i < _reader.FieldCount; i++)
      {
         switch (_reader[i].GetType().ToString())
         {
            case "System.DateTime":
               Field = ((DateTime)_reader[i]).ToString("yyyy-MM-dd HH:mm:ss");
               break;
            case "System.Decimal":
               Field = _reader[i].ToString().Replace(",", ".");
               break;
            case "System.Double":
               Field = _reader[i].ToString().Replace(",", ".");
               break;
            default:
               Field = _reader[i].ToString().Replace(Delimiter, " ").Replace("\r", " ").Replace("\n", " ").Replace("  ", " ");
               if (Field.Length > 5000)
                  Field = Field.Substring(1, 5000);
               break;
         }
         if (i != _reader.FieldCount - 1)
            Field += Delimiter;
         else
            Field += Terminator;
         cnt = enc.GetBytes(Field, 0, Field.Length, buffer, 0);
         _ms.Write(buffer, 0, cnt);
      }
   }
   _ms.Position = 0;
}
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247576
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=,

ну опять MemoryStream

запиши для начала во временный файл на диске, его и сжимай.

как заработает - тогда и занимайся оптимизацией
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247577
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

На диск сохранять нельзя по соображениям безопасности.
У меня всё работало, пытаюсь исправить ошибку нехватки памяти.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247578
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=На диск сохранять нельзя по соображениям безопасности.
пароль хардкодить типа - безопасно
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247584
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

требование заказчика :(
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247587
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
реализовать стрим, извлекающий данные из базы(а не из базы толкать данные в стрим)

скормить этот стрим zip'у
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247609
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
Спасибо, это лучшая мысль, жаль не моя ;)
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247629
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=,

тараканы могут быть с длиной потока. Если maxlong вернуть - всё вроде адекватно пакуется.
если бросить NotSupportedException или вернуть -1 без компрессии поток пишется
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247631
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал так:
Код: c#
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.
using (ZipFile zip = new ZipFile())
{
   Stream stream = new MemoryStream();

   zip.AddEntry("text.txt", stream);
   stream.Write(new byte[] { 0xFF, 0xFE }, 0, 2);
   byte[] buffer = new byte[15000];
   
   using (SqlConnection Conn = new SqlConnection("Server=alpha;Database=ReferInfo;Integrated Security=false;User ID=sa;Pwd=Oj7s0Kde"))
   {
      Conn.Open();
      using (SqlCommand Cmd = new SqlCommand("select * from T_DEF order by [id]", Conn))
      {
         
         SqlDataReader reader = Cmd.ExecuteReader();
         string Delimiter = "\t";
         string Terminator = "\n";
         Encoding enc = Encoding.Unicode;
         while (reader.Read())
         {
            string Field = "";
            for (int i = 0; i < reader.FieldCount; i++)
            {
               switch (reader[i].GetType().ToString())
               {
                  case "System.DateTime":
                     Field = ((DateTime)reader[i]).ToString("yyyy-MM-dd HH:mm:ss");
                     break;
                  case "System.Decimal":
                     Field = reader[i].ToString().Replace(",", ".");
                     break;
                  case "System.Double":
                     Field = reader[i].ToString().Replace(",", ".");
                     break;
                  default:
                     Field = reader[i].ToString().Replace(Delimiter, " ").Replace("\r", " ").Replace("\n", " ").Replace("  ", " ");
                     if (Field.Length > 5000)
                        Field = Field.Substring(1, 5000);
                     break;
               }
               if (i != reader.FieldCount - 1)
                  Field += Delimiter;
               else
                  Field += Terminator;
               int cnt = enc.GetBytes(Field, 0, Field.Length, buffer, 0);
               stream.Write(buffer, 0, cnt);
            }
         }
         reader.Close();
      }
   }
   zip.Save(@"c:\test.zip");
}


Stream пухнет и вываливается по OutOfMemoryException.
Что я делаю не так?
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247635
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=,

по SqlDataReaderToStream - вагон и маленькая тележка замечаний
из ридера лучше типизированное значение извлекать (GetDecimal ,GetDateTime и т д)

Field = _reader[i].ToString().Replace(",", "."); - ToString(CultureInfo.InvariantCulture.NumberFormat)
корректнее будет

switch незачем по строке делать

строку лучше StringBuilder'ом собирать
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247640
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=Что я делаю не так?
я же сказал - избавиться от MemoryStream

свой класс наследник от Stream сделать,
переопределить Read, Length
этот стрим и передавать в zip.AddEntry
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247642
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
за замечания большое спасибо, буду исправлять свой "индийский код" :)
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247645
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=,

скорее всего сходу не выйдет - завтра помогу нарисовать нужный стрим
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247646
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

Признаться, я сегодня взял готовый кусок отсюда , но заставить его работать не смог.
Вот он:
Код: c#
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.
public class ThroughMemoryStream : MemoryStream
{
    private long _position;

    public override bool CanSeek { get { return false; } }

    public override void Write(byte[] buffer, int offset, int count)
    {
        base.Write(buffer, offset, count);
        _position += count;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        var msBuffer = GetBuffer();
        var realCount = Math.Min(Length, count);
        Array.Copy(msBuffer, 0, buffer, 0, realCount);

        Array.Copy(msBuffer, realCount, msBuffer, 0, Length - realCount);
        SetLength(Length - realCount);

        return (int)realCount;
    }

    public override long Position
    {
        get { return _position; } 
        set { throw new NotImplementedException(); }
    }
}



Прошу помощи.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247680
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=Прошу помощи.Помощь: SqlClient Streaming Support
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247682
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=Сергей=На диск сохранять нельзя по соображениям безопасности.Если открывать файл с параметрами FileShare.None + FileOptions.DeleteOnClose , то проблем с безопасностью, вероятно, не будет.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247683
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К=Сергей=Прошу помощи.Помощь: SqlClient Streaming Support Поторопился, это не поможет.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247692
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант - заворачивать запросы в for xml raw, root, type, от ридера получать экземпляр SqlXml, открывать у него XmlReader, читать порциями, и отдавать на архивацию.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247758
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поток для скармливания архиватору:
Код: c#
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.
class BStream : Stream
    {
        IEnumerator<byte[]> iterator;
        byte[] buf;
        int pbuf;
       
        public BStream(IEnumerable<byte[]> it)
        {
            iterator = it.GetEnumerator();
            pbuf = 0;
            buf = new byte[0];
        }
        protected bool getNext()
        {
            while (iterator.MoveNext()) // пропустить пустые массивы
            {
                pbuf = 0;
                buf = iterator.Current;
                if (buf.Length > 0) return true;
            }
            return false;
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            int bytesToCopy = buf.Length - pbuf;
            if (bytesToCopy <= 0)
            {
                if (!getNext()) return 0;
                bytesToCopy = buf.Length;
            }
            if (bytesToCopy > count) bytesToCopy = count;
            Buffer.BlockCopy(buf, pbuf, buffer, offset, bytesToCopy);
            pbuf += bytesToCopy;
            return bytesToCopy;
        }

        public override long Length
        {
            get
            {
                //throw new NotSupportedException(); // Ionic.Zip в этом случае запишет без сжатия
                return long.MaxValue;
            }
        }
        public override bool CanRead
        {
            get
            {
                return true;
            }
        }
        public override bool CanSeek
        {
            get
            {
                return false;
            }
        }
        public override bool CanWrite
        {
            get
            {
                return false;
            }
        }
        public override long Position
        {
            get
            {
                throw new NotSupportedException();
            }
            set
            {
                throw new NotSupportedException();
            }
        }

        public override void Flush()
        {
            throw new NotSupportedException();
        }
        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotSupportedException();
        }
        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }
        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException();
        }
    }

...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247778
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алексей КFileShare.None[/b] + [b]FileOptions.DeleteOnClose
ночью мне пришла в голову эта мысль, спасибо!!!
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247792
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, ОГРОМНОЕ спасибо! Сейчас буду пробовать, хоть ничего и не понял из кода.
...
Рейтинг: 0 / 0
Преобразование SqlDataReader в Stream
    #39247798
=Сергей=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
а как правильно употребить BStream?
...
Рейтинг: 0 / 0
25 сообщений из 44, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Преобразование SqlDataReader в Stream
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]