2013-05-07 2 views
-4

Я читаю двоичный файл. Если я читаю один файл, мой код работает нормально. Но когда я читаю файлы в папке, я получаю ошибку, которая вставлена ​​ниже. Я добавлю код, который я использую для чтения файлов. Я чтение файлов в массиве байт:Исключение из памяти в цикле цикла C#

byte[] b = File.ReadAllBytes(args); 

и хранении данных в массиве (ориентировочный код):

len=400000000; 
public ArrayList rawData1 = new ArrayList(); 
UInt32[] fff = Enumerable.Repeat((UInt32)4095, len/4).ToArray();  


public ReadRawFiles{ 
      while (true){ 
      rawData1.Add((double)(BitConverter.ToUInt32(b, curPos) & fff[i])); 
      i++; 
      } 
} 
b=null; //clear array 

Это работает, если я прочитал только один файл, хотя и медленный (размер около 40 МБ) , Но когда я добавляю путь к папке и читаю снова, я получаю сообщение об ошибке.

List<ReadRawFiles> list = new List<ReadRawFiles>(); 
ReadRawFiles rawFiles; 
foreach (var f in sFiles) 
        { 
         rawFiles = new ReadRawFiles(f.File,true,true); 
         list.Add(rawFiles); 

         //rawFiles=null; //clear?? 
        } 

Я не очень понимаю, как работает сборщик мусора. Пожалуйста, дайте мне знать, если я что-то пропустил.

Большое спасибо.

Edit: коды: http://www.codesend.com/view/4aadd067dfd26ea88396afbd3cd3fc22/ http://www.codesend.com/view/f8f798224e54c28a00865ca9aff514e5/

System.OutOfMemoryException was unhandled 
    Message=Exception of type 'System.OutOfMemoryException' was thrown. 
    Source=System.Core 
    StackTrace: 
     at System.Linq.Buffer`1.ToArray() 
     at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 
     at program.ReadRawFiles..ctor(String args, Nullable`1 flagraw, Nullable`1 dualChannel) in E:\projects\development\vs_test\WpfApplication1\WpfApplication1\param.cs:line 83 
     at SePSI.MainWindow.Add_folder(Object sender, RoutedEventArgs e) in E:\projects\development\vs_test\WpfApplication1\WpfApplication1\MainWindow.xaml.cs:line 196 
     at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 
     at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
     at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 
     at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) 
     at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg) 
     at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
     at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
     at System.Windows.Threading.DispatcherOperation.InvokeImpl() 
     at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) 
     at System.Threading.ExecutionContext.runTryCode(Object userData) 
     at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Windows.Threading.DispatcherOperation.Invoke() 
     at System.Windows.Threading.Dispatcher.ProcessQueue() 
     at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
     at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
     at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
     at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
     at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
     at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
     at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
     at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 
     at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
     at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 
     at System.Windows.Application.RunDispatcher(Object ignore) 
     at System.Windows.Application.RunInternal(Window window) 
     at System.Windows.Application.Run(Window window) 
     at System.Windows.Application.Run() 
     at SePSI.App.Main() in E:\projects\development\vs_test\WpfApplication1\WpfApplication1\obj\x86\Debug\App.g.cs:line 0 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
+3

ли вывесить фактический код , Кроме того, как следует из названия исключения, у вас заканчивается память. Довольно нормально, если вы храните кучу больших файлов в памяти. – ken2k

+0

Сколько файлов находится в этой папке и сколько памяти они принимают вместе? – Corak

+4

'while (true)' ??? –

ответ

4

Здесь есть некоторые очень неэффективные детали; загружая целые файлы в память для одного, и непонятный массив fff для другого. ArrayList, который содержит double для третьего (который включает в себя бокс каждый double - очень плохо здесь).

я настоятельно рекомендую пытаюсь упростить и поток данные, например:

byte[] buffer = new byte[4]; 
List<double> rawData = new List<double>(); 
foreach(var path in paths) 
{ 
    using(var file = File.OpenRead(path)) 
    { 
     while(TryRead(file, buffer, 4)) 
     { 
      const uint MASK = 4095; 
      var val = BitConverter.ToUInt32(buffer, 0) & MASK; 
      // note that this line looks really dodgy 
      rawData.Add((double)val); 
     } 
    } 
} 

с использованием методы полезности, чтобы заполнить весь кусок 4 байта (или не):

static bool TryRead(Stream s, byte[] buffer, int bytes) 
{ 
    int read = s.Read(buffer, 0, bytes), offset; 
    if (read <= 0) return false; // no more data 

    bytes -= read; 
    offset = read; 
    while (bytes > 0 && (read = s.Read(buffer, offset, bytes)) > 0) 
    { 
     bytes -= read; 
     offset += read; 
    } 
    if (bytes != 0) throw new EndOfStreamException(); 
    return true; // success 
} 

Следует, однако, подчеркнуть, что:

  • uint-to-double конверсия выглядит очень маловероятной; что не как бы вы читали двойной, как двоичный
  • хранить все данные как double звучит одинаково маловероятно, - я не могу думать о каких-либо очевидных сценариев, где это было бы полезно
+0

Я воспроизвожу код matlab, вот как это было реализовано там. Я попробую то, что вы сказали. Большое спасибо. – Naresh

+0

и мой файл составляет 40 МБ, не так ли быстро прочитать все это в памяти и очистить, как только вы закончите с ним? – Naresh

+2

@Naresh 40 MB по-прежнему довольно значителен. Вы знаете, что быстрее, чем выделение 40 МБ? * не * выделение 40 МБ! Особенно, если вы находитесь в 32-битном процессе и уничтожаете кучу больших объектов. Аналогично, массив 98FB 'fff', который *** полностью необъяснен ***, нанесет большой вред. Огромное количество бокса ('ArrayList') - еще одна огромная проблема. Поскольку код в вопросе очень неясен, я могу предложить только указатели ... –

1

Я бы предположил, что было бы в связи с этим:

while (true) 
{ 
    rawData1.Add((double)(BitConverter.ToUInt32(b, curPos) & fff[i])); 
    i++; 
} 

Вы не условие завершения, оно будет продолжаться вечно, и продолжает есть ресурсы, увеличивая i и добавляя данные в rawData ArrayList.

+4

Код OP не имеет смысла (см. «Индикаторный код»), и, поскольку он работает для одного файла, давайте предположим, что в * актуальном * коде нет бесконечного цикла. – ken2k

+0

@ ken2k - Я не вижу, как условие прекращается. То, что работает для 1 файла, на самом деле не может быть, то есть OP видит желаемый результат, но программа все еще потребляет ненужную память, однако исключение не было выбрано. –

+0

i установлен в 0 для файла, и я прочитал 2 файла, прежде чем получить исключение. – Naresh

Смежные вопросы