SukirtiShetty Ответов: 1

Системы исключению нехватки памяти


Я написал свой код для преобразования Excel в другой формат с разделителями, но он выбрасывает исключение System. outof memory
Мой код выглядит следующим образом


Пожалуйста, помогите мне в этом

Что я уже пробовал:

<pre>string excelConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + ";Extended Properties=Excel 12.0;";
                        OleDbConnection excelConn = new OleDbConnection(excelConnStr);
                        excelConn.Open();
                        DataTable dbSchema = excelConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                        string strsheetName = "Sheet1$";
                        if (dbSchema != null && dbSchema.Rows.Count > 0)
                        {
                            strsheetName = Convert.ToString(dbSchema.Rows[0]["TABLE_NAME"]);
                        }

                        System.Data.DataTable dtPatterns = new System.Data.DataTable();
                        excelCommand = new OleDbCommand("SELECT * FROM [" + strsheetName + "]", excelConn);
                        excelDataAdapter.SelectCommand = excelCommand;
                        excelDataAdapter.Fill(dtPatterns);
                        
                        List<string> xcelData = new List<string>();
                        List<string> ColumnNames = new List<string>();
                        ds.Tables.Add(dtPatterns);
                        totalRowsCount = dtPatterns.Rows.Count;
                        totalColumnsCount = dtPatterns.Columns.Count;
                       
                        for (int c = 0; c < dtPatterns.Columns.Count; c++)
                        {
                            if (c == dtPatterns.Columns.Count - 1)
                            {
                                SB1.Append(cValue.ToString() + dtPatterns.Columns[c].ToString() + cValue.ToString());
                            }
                            else
                            {
                                SB1.Append(cValue.ToString() + dtPatterns.Columns[c].ToString() + cValue.ToString() + sValue.ToString());
                            }
                        }
                        SB1.Append("\r\n");
                        for (int d = 0; d < dtPatterns.Rows.Count; d++)
                        {
                            this.toolStripStatusLabel1.Text = string.Format("Processing Please Wait ...{0} of {1}", (count + 1), totalRowsCount);
                            for (int c = 0; c < dtPatterns.Columns.Count; c++)
                            {
                                int g = dtPatterns.Columns.Count - 1;
                                if (c == g)
                                {
                                    SB1.Append(cValue.ToString() + dtPatterns.Rows[d][c].ToString() + cValue.ToString());
                                }
                                else
                                {
                                    SB1.Append(cValue.ToString() + dtPatterns.Rows[d][c].ToString() + cValue.ToString() + sValue.ToString());
                                }
                            }
                            SB1.Append("\r\n");
                            count++;
                        }

CHill60

У вас может быть бесконечный цикл. Вы пробовали отлаживать, чтобы убедиться, что вы увеличиваете счетчик на всех маршрутах

SukirtiShetty

Да, и я отладил код. Он отлично работает для 1000 строк в Excel. Он выдает ошибку, когда строки более 1,00,000 в файле Excel

sameer549

когда вы работаете с объемными данными, вам нужно читать строки в кусках/цикле, например, 1000 строк каждый раз

Richard MacCutchan

Тогда не читайте так много строк в одном запросе. Научитесь работать в рамках вашей системы.

SukirtiShetty

Мне нужны были разделители, поэтому я использовал цикл for для получения данных из excel

sameer549

да, но stringBuilder не может удерживать строку для лакхов записей, определенно он выбрасывает исключение памяти в какой-то момент.

SukirtiShetty

не могли бы вы дать мне некоторое представление о том, как я могу достичь тех же результатов, используя свой код

1 Ответов

Рейтинг:
2

CHill60

Альтернативой использованию StringBuilder для хранения всей электронной таблицы является запись прямо в текстовый файл - см. Как сделать запись в текстовый файл (руководство по программированию на C#) | Microsoft Docs[^]. Вы можете использовать StringBuilder для каждой строки, прежде чем записывать ее в файл (что поможет ускорить ее работу). Вы должны использовать

sb.Clear();
цикл for each.

Если вы не хотите вносить такие большие изменения в свой существующий код (который мы не можем запустить - слишком много объявлений и т. д. отсутствует), то окружите dataread циклом, который обрабатывает только, скажем, 1000 строк...
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= rowcount; i += 1000)
{
    // in here handle only 1000 rows from the spreadsheet

    //After handling the 1000 rows ...

    // Write the contents of sb to the file
    // then do this sb.Clear(); or if you don't have that version of .NET...
    sb = new StringBuilder();
}