Forum: PC-Programmierung C#: Was löst die Exception aus?


von Bernd (Gast)


Lesenswert?

C#, Visual Studio Express 2013, Windows 8.1

Die Funktion readsector(..) ruft die Function Read(...) auf.

Beträgt die Länge von "byte[] buffer" 512 bekomme ich beim Aufruf
von Read(..) eine Exception, wenn ich einen Sektor größer 0 lesen
will. Bei einer Länge von 1024 kommt die Exception an dem Sektor 513.
Je länger "buffer" ist, desto höhere Sektoren können gelesen werden.

Was hat die Länge von "buffer" mit der Sektornummer in "sector" zu tun?

Die Exception tritt auch auf, wenn in Read(...) die Zeilen von "long a"
bis zur abschließenden Klammer des IFs auskommentiert werden. D. h. das
Problem hat wahrscheinlich etwas mit dem Aufruf von Read(...) zu tun.

Eine Recherche - Stack Flow, Microsoft - hat keine Erkenntnisse 
gebracht.

Wo liegt der Fehler bzw. was ist zu tun um ihn einzugrenzen?
1
Offset and length were out of bounds for the array or count is greater than
2
the number of elements from index to the end of the source collection.

1
public void readsector(byte[] buffer, int sector, int amount)
2
{
3
  var reader = new BinaryReader(new DeviceStream(@"\\.\PHYSICALDRIVE6"));
4
5
  try
6
  {
7
    reader.Read(buffer, sector, amount);                  
8
  }
9
  catch (Exception e)
10
  {
11
    Console.WriteLine(e.Message);
12
  }
13
  reader.Close(); 
14
}

1
public override int Read(byte[] buffer, int sector, int amount)
2
{
3
  int BytesRead = 0;
4
5
  long a;
6
  SetFilePointerEx(handleValue, sector * 512, out a, 0);
7
  
8
  if (!ReadFile(handleValue.DangerousGetHandle(), buffer, amount, ref BytesRead, IntPtr.Zero))
9
  {
10
    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
11
  }
12
13
  return BytesRead;
14
}

von Jim M. (turboj)


Lesenswert?

Ist das was modernes? HDDs und SSDs haben 4KB Sektoren heutzutage.

Das OS könnte für die ersten 512 Bytes des Sektor 0 eine Ausnahme 
machen, damit veraltete Software eine Partitionstabelle lesen kann.

Du beachtest nicht den Rückgabecode für SetFilePointerEx(), das kann bei 
4k Sektoren schief gehen.

von Dirk K. (merciless)


Lesenswert?

Wie groß ist
1
amount
?

Mir kommt deine Buffergröße zu klein vor.

Was zur Info:
https://docs.microsoft.com/en-us/dotnet/api/system.io.binaryreader.read?view=netframework-4.7.2

https://stackoverflow.com/questions/19558435/what-is-the-best-buffer-size-when-using-binaryreader-to-read-big-files-1-gb/19837238#19837238
Zitat:
If you do your own buffering, use large request sizes (64 KB is a good 
place to start).

merciless

von Bernd (Gast)


Lesenswert?

Vielen Dank für eure Beiträge und Links.

@ Jim

SD-Card (2 GBytes, FAT16) mit 512-Bytes Sektoren.

@ Dirk

amount ist 512

> Mir kommt deine Buffergröße zu klein vor.

Kann gut sein, dass eine tieferliegende Funktion einen größeren Bereich 
ließt, den entsprechenden Buffer benötigt, aber nur 512 Bytes zurückgibt 
und bestätigt.

von Dirk K. (merciless)


Lesenswert?

In dem ersten Link, den ich gepostet habe, steht
beschrieben, wann welche Exceptions geworfen werden.
Hast du das mal durchgelesen?

merciless

von Bernd (Gast)


Lesenswert?

Dirk K. schrieb:

> In dem ersten Link, den ich gepostet habe, steht
> beschrieben, wann welche Exceptions geworfen werden.
> Hast du das mal durchgelesen?
>
> merciless

Ja.
1
The buffer length minus index is less than count.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.