C# 从 Byte[] 读取和写入 Char[] - 使用解决方案更新

发布于 2024-08-26 18:23:43 字数 4287 浏览 6 评论 0原文

我有一个大约 10,000 字节的字节数组,它基本上是来自 delphi 的 blob,其中包含 char、string、double 和各种类型的数组。这需要通过 C# 读入和更新。

我创建了一个非常基本的读取器,它从数据库获取字节数组,并在访问工作正常的属性时将字节转换为相关的对象类型。我的问题是,当我尝试写入特定的 char[] 项时,它似乎没有更新字节数组。我创建了以下用于读取和写入的扩展:

public static class CharExtension
{
    public static byte ToByte( this char c )
    {
        return Convert.ToByte( c );
    }

    public static byte ToByte( this char c, int position, byte[] blob )
    {
        byte b = c.ToByte();
        blob[position] = b;
        return b;
    }
}

public static class CharArrayExtension
{
    public static byte[] ToByteArray( this char[] c )
    {
        byte[] b = new byte[c.Length];

        for ( int i = 1; i < c.Length; i++ )
        {
            b[i] = c[i].ToByte();
        }

        return b;
    }

    public static byte[] ToByteArray( this char[] c, int positon, int length, byte[] blob )
    {
        byte[] b = c.ToByteArray();

        Array.Copy( b, 0, blob, positon, length );

        return b;
    }
}

public static class ByteExtension
{
    public static char ToChar( this byte[] b, int position )
    {
        return Convert.ToChar( b[position] );
    }
}

public static class ByteArrayExtension
{
    public static char[] ToCharArray( this byte[] b, int position, int length )
    {
        char[] c = new char[length];

        for ( int i = 0; i < length; i++ )
        {
            c[i] = b.ToChar( position );
            position += 1;
        }

        return c;
    }
}

读取和写入字符和字符数组 我的代码如下所示:

Byte[] _Blob; // set from a db field

public char ubin
{
    get { return _tariffBlob.ToChar( 14 ); }
    set { value.ToByte( 14, _Blob ); }
}

public char[] usercaplas
{
    get { return _tariffBlob.ToCharArray( 2035, 10 ); }
    set { value.ToByteArray( 2035, 10, _Blob ); }
}

因此,写入我可以执行的对象:

ubin = 'C'; // this will update the byte[]
usercaplas = new char[10] { 'A', 'B', etc. }; // this will update the byte[]

usercaplas[3] = 'C'; // this does not update the byte[]

我知道原因是 setter 属性没有被调用,但我想知道是否有一种方法可以使用类似于我已有的代码来解决这个问题?

我知道一个可能的解决方案是使用一个名为 _usercaplas 的私有变量,我根据需要设置和更新该变量,但是由于字节数组的长度接近 10,000 字节,所以类已经很长了,我想要一种更简单的方法来减少总体代码长度和复杂性。

感谢

解决方案

如果有人需要的话,这是我的解决方案。如果您有更好的方法,请告诉我。

首先,我为数组创建了一个新类:

public class CharArrayList : ArrayList
{
    char[] arr;
    private byte[] blob;
    private int length = 0;
    private int position = 0;

    public CharArrayList( byte[] blob, int position, int length )
    {
        this.blob = blob;
        this.length = length;
        this.position = position;

        PopulateInternalArray();
        SetArray();
    }

    private void PopulateInternalArray()
    {
        arr = blob.ToCharArray( position, length );
    }

    private void SetArray()
    {
        foreach ( char c in arr )
        {
            this.Add( c );
        }
    }

    private void UpdateInternalArray()
    {
        this.Clear();

        SetArray();
    }

    public char this[int i]
    {
        get
        {
            return arr[i];
        }
        set
        {
            arr[i] = value;
            UpdateInternalArray();
        }
    }
}

然后我创建了几个扩展方法来帮助转换为 byte[]

    public static byte[] ToByteArray( this CharArrayList c )
    {
        byte[] b = new byte[c.Count];

        for ( int i = 0; i < c.Count; i++ )
        {
            b[i] = Convert.ToChar( c[i] ).ToByte();
        }

        return b;
    }

    public static byte[] ToByteArray( this CharArrayList c, byte[] blob, int position, int length )
    {
        byte[] b = c.ToByteArray();

        Array.Copy( b, 0, blob, position, length );

        return b;
    }

因此读取和写入对象:

    private CharArrayList _usercaplass;
    public CharArrayList usercaplas
    {
        get 
        {
            if ( _usercaplass == null )
                _usercaplass = new CharArrayList( _tariffBlob, 2035, 100 );

            return _usercaplass;
        }
        set 
        {
            _usercaplass = value;
            _usercaplass.ToByteArray( _tariffBlob, 2035, 100 );
        }
    }

正如前面提到的,它不是一个理想的解决方案,因为我必须拥有私有设置器中的变量和额外代码,但我找不到解决方法。

I have a byte array of around 10,000 bytes which is basically a blob from delphi that contains char, string, double and arrays of various types. This need to be read in and updated via C#.

I've created a very basic reader that gets the byte array from the db and converts the bytes to the relevant object type when accessing the property which works fine. My problem is when I try to write to a specific char[] item, it doesn't seem to update the byte array. I've created the following extensions for reading and writing:

public static class CharExtension
{
    public static byte ToByte( this char c )
    {
        return Convert.ToByte( c );
    }

    public static byte ToByte( this char c, int position, byte[] blob )
    {
        byte b = c.ToByte();
        blob[position] = b;
        return b;
    }
}

public static class CharArrayExtension
{
    public static byte[] ToByteArray( this char[] c )
    {
        byte[] b = new byte[c.Length];

        for ( int i = 1; i < c.Length; i++ )
        {
            b[i] = c[i].ToByte();
        }

        return b;
    }

    public static byte[] ToByteArray( this char[] c, int positon, int length, byte[] blob )
    {
        byte[] b = c.ToByteArray();

        Array.Copy( b, 0, blob, positon, length );

        return b;
    }
}

public static class ByteExtension
{
    public static char ToChar( this byte[] b, int position )
    {
        return Convert.ToChar( b[position] );
    }
}

public static class ByteArrayExtension
{
    public static char[] ToCharArray( this byte[] b, int position, int length )
    {
        char[] c = new char[length];

        for ( int i = 0; i < length; i++ )
        {
            c[i] = b.ToChar( position );
            position += 1;
        }

        return c;
    }
}

to read and write chars and char arrays my code looks like:

Byte[] _Blob; // set from a db field

public char ubin
{
    get { return _tariffBlob.ToChar( 14 ); }
    set { value.ToByte( 14, _Blob ); }
}

public char[] usercaplas
{
    get { return _tariffBlob.ToCharArray( 2035, 10 ); }
    set { value.ToByteArray( 2035, 10, _Blob ); }
}

So to write to the objects I can do:

ubin = 'C'; // this will update the byte[]
usercaplas = new char[10] { 'A', 'B', etc. }; // this will update the byte[]

usercaplas[3] = 'C'; // this does not update the byte[]

I know the reason is that the setter property is not being called but I want to know is there a way around this using code similar to what I already have?

I know a possible solution is to use a private variable called _usercaplas that I set and update as needed however as the byte array is nearly 10,000 bytes in length the class is already long and I would like a simpler approach as to reduce the overall code length and complexity.

Thank

Solution

Here's my solution should anyone want it. If you have a better way of doing then let me know please.

First I created a new class for the array:

public class CharArrayList : ArrayList
{
    char[] arr;
    private byte[] blob;
    private int length = 0;
    private int position = 0;

    public CharArrayList( byte[] blob, int position, int length )
    {
        this.blob = blob;
        this.length = length;
        this.position = position;

        PopulateInternalArray();
        SetArray();
    }

    private void PopulateInternalArray()
    {
        arr = blob.ToCharArray( position, length );
    }

    private void SetArray()
    {
        foreach ( char c in arr )
        {
            this.Add( c );
        }
    }

    private void UpdateInternalArray()
    {
        this.Clear();

        SetArray();
    }

    public char this[int i]
    {
        get
        {
            return arr[i];
        }
        set
        {
            arr[i] = value;
            UpdateInternalArray();
        }
    }
}

Then I created a couple of extension methods to help with converting to a byte[]

    public static byte[] ToByteArray( this CharArrayList c )
    {
        byte[] b = new byte[c.Count];

        for ( int i = 0; i < c.Count; i++ )
        {
            b[i] = Convert.ToChar( c[i] ).ToByte();
        }

        return b;
    }

    public static byte[] ToByteArray( this CharArrayList c, byte[] blob, int position, int length )
    {
        byte[] b = c.ToByteArray();

        Array.Copy( b, 0, blob, position, length );

        return b;
    }

So to read and write to the object:

    private CharArrayList _usercaplass;
    public CharArrayList usercaplas
    {
        get 
        {
            if ( _usercaplass == null )
                _usercaplass = new CharArrayList( _tariffBlob, 2035, 100 );

            return _usercaplass;
        }
        set 
        {
            _usercaplass = value;
            _usercaplass.ToByteArray( _tariffBlob, 2035, 100 );
        }
    }

As mentioned before its not an ideal solutions as I have to have private variables and extra code in the setter but I couldnt see a way around it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文