Comment passer un tableau d'octets en lecture seule?
-
17-09-2020 - |
Question
Penser le code suivant:
static int Main() {
byte[] data = File.ReadAllBytes("anyfile");
SomeMethod(data);
...
}
static void SomeMethod(byte[] data) {
data[0] = anybytevalue; // this line should not be possible!!!
byte b = data[0]; // only reading should be allowed
...
}
Est-il un moyen de lecture-seule en passant le byte[] en C#?La copie n'est pas une solution.Je ne voudrais pas gaspiller la mémoire (parce que le fichier peut être très grand).Veuillez garder des performances à l'esprit!
La solution
Vous pouvez passer une ReadOnlyCollection<byte>
, comme ceci:
static int Main() {
byte[] data = File.ReadAllBytes("anyfile");
SomeMethod(new ReadOnlyCollection<byte>(data));
...
}
static void SomeMethod(ReadOnlyCollection<byte> data) {
byte b = data[0]; // only reading is allowed
...
}
Cependant, il serait mieux de passer un Stream
, comme ceci:
De cette façon, vous n'aurez pas lu tout le fichier en mémoire à tous.
static int Main() {
Stream file = File.OpenRead("anyfile");
SomeMethod(file);
...
}
static void SomeMethod(Stream data) {
byte b = data.ReadByte(); // only reading is allowed
...
}
Autres conseils
Je pense que cela pourrait être ce que vous recherchez.
Compilez le code ci-dessous et vous obtiendrez cette erreur de compilation:
public class MyReadOnlyBytes
{
private byte[] myData;
public MyReadOnlyBytes(byte[] data)
{
myData = data;
}
public byte this[int i]
{
get
{
return myData[i];
}
}
}
class Program
{
static void Main(string[] args)
{
var b = File.ReadAllBytes(@"C:\Windows\explorer.exe");
var myb = new MyReadOnlyBytes(b);
Test(myb);
Console.ReadLine();
}
private static void Test(MyReadOnlyBytes myb)
{
Console.WriteLine(myb[0]);
myb[0] = myb[1];
Console.WriteLine(myb[0]);
}
}
Je voudrais vous recommandons d'utiliser le plus possible de l'objet dans la hiérarchie qui fait le travail.Dans votre cas, ce serait IEnumerable<byte>
:
static int Main()
{
byte[] data = File.ReadAllBytes("anyfile");
SomeMethod(data);
}
static void SomeMethod(IEnumerable<byte> data)
{
byte b = data.ElementAt(0);
// Notice that the ElementAt extension method is sufficiently intelligent
// to use the indexer in this case instead of creating an enumerator
}