C#-读写8位以上的符号

我正在尝试编写一个编码文件,该文件有9到12位符号.写入文件时,我想它不能正确写入9位符号,因为我无法解码该文件.尽管文件中只有8位符号.一切正常.这就是我写文件的方式

File.AppendAllText(outputFileName, WriteBackContent, ASCIIEncoding.Default);

使用ReadAllText函数调用进行读取也是如此.

去这里的路是什么?

我正在使用ZXing库使用RS编码器对文件进行编码.

 ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);//if i use AZTEC_DATA_8 it works fine beacuse symbol size is 8 bit
 int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c);
 enc.encode(bytesAsInts, parity);
 byte[] bytes = bytesAsInts.Select(x => (byte)x).ToArray();
 string contentWithParity = (ASCIIEncoding.Default.GetString(bytes.ToArray()));
 WriteBackContent += contentWithParity;
 File.AppendAllText(outputFileName, WriteBackContent, ASCIIEncoding.Default);

就像代码中一样,我正在使用AZTEC_DATA_12初始化我的编码器,这意味着12位符号.由于RS Encoder需要int数组,因此我将其转换为int数组.像这样写入文件,但是由于AZTEC_DATA_8是8位符号,所以它可以很好地工作,但是AZTEC_DATA_12则不能.

解决方法:

主要问题在这里:

byte[] bytes = bytesAsInts.Select(x => (byte)x).ToArray();

当将单个整数转换为单个字节时,您基本上会丢弃部分结果.

如果在调用encode()之后查看数组,则可以看到某些数组元素的值大于255,因此无法将其表示为字节.但是,在上面引用的代码中,您将整数数组中的每个单个元素都转换为字节,当其值大于255时更改了该元素.

因此,要存储encode()的结果,必须以不丢失或修改值的方式将整数数组转换为字节数组.

为了在字节数组和整数数组之间进行这种转换,可以使用函数Buffer.BlockCopy().如何使用此函数的示例是in this answer.

将答案的样本和注释到答案的样本用于两次转换:将字节数组转换为整数数组,以传递给encode()函数,并将从encode()函数返回的整数数组转换为字节数组.

以下是链接的答案中的示例代码:

// Convert byte array to integer array
byte[] result = new byte[intArray.Length * sizeof(int)];
Buffer.BlockCopy(intArray, 0, result, 0, result.Length);

// Convert integer array to byte array (with bugs fixed)
int bytesCount = byteArray.Length;
int intsCount = bytesCount / sizeof(int);
if (bytesCount % sizeof(int) != 0) intsCount++;
int[] result = new int[intsCount];            
Buffer.BlockCopy(byteArray, 0, result, 0, byteArray.Length);

现在有关将数据存储到文件中:不要直接通过Encoding.GetString()将数据转换为字符串.并非所有位序列都是任何给定字符集中字符的有效表示.因此,将随机字节的随机序列转换为字符串有时会失败.

而是通过File.WriteAllBytes()/ File.ReadAllBytes()将字节数组直接存储/读取到文件中,或者使用Convert.ToBase64()和Convert.FromBase64()来处理字节数组的base64编码的字符串表示形式.

以下是一些示例代码:

    ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);//if i use AZTEC_DATA_8 it works fine beacuse symbol size is 8 bit
    int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c);
    enc.encode(bytesAsInts, parity);

    // Turn int array to byte array without loosing value
    byte[] bytes = new byte[bytesAsInts.Length * sizeof(int)];
    Buffer.BlockCopy(bytesAsInts, 0, bytes, 0, bytes.Length);

    // Write to file
    File.WriteAllBytes(outputFileName, bytes);

    // Read from file
    bytes = File.ReadAllBytes(outputFileName);            

    // Turn byte array to int array 
    int bytesCount = bytes.Length * 40;
    int intsCount = bytesCount / sizeof(int);
    if (bytesCount % sizeof(int) != 0) intsCount++;
    int[] dataAsInts = new int[intsCount];
    Buffer.BlockCopy(bytes, 0, dataAsInts, 0, bytes.Length);

    // Decoding
    ReedSolomonDecoder dec = new ReedSolomonDecoder(GenericGF.AZTEC_DATA_12);
    dec.decode(dataAsInts, parity);
上一篇:c#-System.IO.IOException:该进程无法访问文件,因为它正在被另一个进程使用


下一篇:首页> C#>如何应用包含在最后的记录和删除如果在LINQ找到?