C:将整个文件读入缓冲区并将字节切换为buf | ADDECEFA - > DEADFACE

时间:2016-12-14 20:48:44

标签: c performance buffer byte-shifting

编辑:在做了一些研究后,似乎我真正需要的是大端到中端,反之亦然。所以12345678 - > 34127856然后回来。抱歉有任何困惑。

我有一个小文件,正好是16MB。我正在将整个文件读入缓冲区。我想要做的是尽可能地将整个文件/缓冲区切换为一次(例如,均匀/全局交换ADDECEFA => DEADFACE)。我已经阅读了无数的byteswapping页面,但由于某些原因(很可能是愚蠢的大脑),很多bitwise / byteswap的东西都在我脑海中。如果有人知道dummies的bitwise / byteswap,请指出我正确的方向!

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) 
{

    const char * suffix = ".reversed";

    FILE *input = fopen(argv[1], "rb");
    char * out = strcat(argv[1], suffix);
    FILE *output = fopen(out, "wb");

    int data[16384];
    int swapped;

 while(fread(data,sizeof data, 1, input)){

    swapped = ((data & 0x000000FF) << 24) |
              ((data & 0x0000FF00) <<  8) |
              ((data & 0x00FF0000) >>  8) |
              ((data & 0xFF000000) >> 24);

    fwrite(swapped, sizeof data , 1, output);

            /*  by golly it copies the file fast as heck!
                but i am unsure how to manipulate 'data' buffer
                so as it uniformly/globaly swaps ADDECEFA => DEADFACE 
            */
        }
    }

另外,如果你看到我在代码中做错了什么,请告诉我并向我展示一个更好的方法。如果您需要我详细说明,请不要犹豫。谢谢,并有一个很好的。

编辑:我添加了一个失败的尝试。我的最终目标是交换字节,因为我将其写回outfile并尽可能高效地交换它们。

1 个答案:

答案 0 :(得分:1)

鉴于

int data[16384];

此代码

while(fread(data,sizeof data, 1, input)){

将尝试从int读取16,384 input个值。到目前为止没有错。

但是这段代码:

swapped = ((data & 0x000000FF) << 24) |
          ((data & 0x0000FF00) <<  8) |
          ((data & 0x00FF0000) >>  8) |
          ((data & 0xFF000000) >> 24);

将尝试填充data的字节交换地址的任何部分到swapped,因为data被评估为地址数组的第一个元素。

你可能想要这样的东西:

swapped = ((data[ 0 ] & 0x000000FF) << 24) |
          ((data[ 0 ] & 0x0000FF00) <<  8) |
          ((data[ 0 ] & 0x00FF0000) >>  8) |
          ((data[ 0 ] & 0xFF000000) >> 24);

但这有一个问题,即转移签名的 int值具有实现定义的行为。见Arithmetic bit-shift on a signed integer

所以你可能想要

unsigned int data[16384];

尽管如此,您只需交换一个int值。您需要遍历已读取的所有数据,交换每个int,假设这是您想要做的。

这引发了另一个问题 - 您的代码不会跟踪字节交换所需的数据量。您需要计算读入的int值和使用的数量。

最后,这段代码

fwrite(swapped, sizeof data , 1, output);

会将sizeof data字节写入output,从指向swapped的地址开始。但这是swapped的定义:

int swapped;

因此fwrite()调用是未定义的行为。