2013-03-11 4 views
-1

Сначала я написал код с помощью StringBuilder и ударил Out Of Memory Exception, прочитал связанные вопросы и изменил его на строку + =, но все еще получал ту же ошибку OOM.Out Of Memory on String и StringBuilder

У меня есть ~ 2100 + файлы разных размеров и всего ~ 200 МБ +.

Из-за ограничений я не могу использовать доступ к файлам в режиме присоединения. Любые санкции?

const string myPath = @"C:\values\"; 

var files = Directory.EnumerateFiles(myPath).Select(Path.GetFileNameWithoutExtension); 
var filesGrouped = files.Where(f => f.Length > 12).GroupBy(f => f.Substring(0, f.Length - 9)).OrderBy(f => f.Key).ToList(); 

filesGrouped.ForEach(fg => 
    { 
     var myRows = string.Empty; 

     // download files 
     fg.ToList().ForEach(gf => 
      { 
       string myFile; 
       string fileToRead = string.Format("{0}{1}.csv", myPath, gf); 
       using (var sr = new StreamReader(fileToRead)) myFile = sr.ReadToEnd(); 
       //! OOM Error hits the line below 
       myRows += myFile + ControlChars.NewLine; 
      }); 

     // upload new file 
     using (var sw = new StreamWriter(myPath + fg.Key + ".csv", false, Encoding.UTF8)) sw.Write(myRows); 
    }); 
+2

Sidenote: заменить 'ControlChars.NewLine' на' Environment.NewLine'. –

ответ

1

Вы можете попробовать:

filesGrouped.ForEach(fg => 
{ 
    using (var sw = new StreamWriter(myPath + fg.Key + ".csv", false, Encoding.UTF8)) 
    { 
     fg.ToList().ForEach(gf => 
     { 
      string fileToRead = string.Format("{0}{1}.csv", myPath, gf); 
      using (var sr = new StreamReader(fileToRead)) 
      { 
       foreach (var line in sr.ReadLine()) 
       { 
        sw.WriteLine(line); 
       } 
       sw.Write(Environment.NewLine); 
      } 
     }); 

    } 
}); 

Если это также не удается (содержимое файла на одной строке), вы должны возможность использовать один и тот же принцип, StreamReader.Read в сочетании с StreamWriter.Write.

+0

спасибо! он работал с небольшим исправлением. Спасибо за ваше время и внимание! – cilerler

+0

, кстати, я попытался отредактировать код, но выглядел как не обновленный. для того, чтобы заставить работу над кодом заменить внутреннюю часть **, используя (var sr = ...) ** с ** while (! sr.EndOfStream) sw.WriteLine (sr.ReadLine()); ** – cilerler