c - 使用 fwrite() 写入某些字节时出错

标签 c file-io io

自本文最初发布以来,某些事情已经发生了变化。我已经用编辑标题标记了它们。

我正在从不同格式的源写入图像文件。这是 1024x1024 的数据,每个像素有 2 个字节。

源图像格式和目标图像格式均包含可变字节数的 header (包含元数据,例如每个像素的字节数等),然后是图像数据。

不知道是否相关,但我们正在使用一个有 40 多年历史的软件(称为 Mcidas)来显示这些图像 以前,我将两个字节读入一个 unsigned Short 数组。然后一些位操作将它们连接成一个新的无符号短。然后,我使用 fwrite() 函数将它们写入目标文件。

编辑
我现在直接在 data 上使用 fread()

读取操作运行良好(尝试了fputc()fread())

编辑
两个文件的十六进制转储的图像数据部分完全匹配。然而,由于某种原因,图像似乎在某些字节中显示出位错误。源文件似乎也很干净。

这是图像(2MB 文件):
http://pdsimage.wr.usgs.gov/archive/mess-e_v_h-mdis-2-edr-rawdata-v1.0/MSGRMDS_1001/DATA/2007_156/EW0089565661F.IMG

您可以将其另存为“source.IMG”来测试它。

下面是源图像和最终图像的比较,其中第一行进行了行扫描。

Source file and Image

请注意某些像素的突然跳跃,这会产生轮廓。这些长度似乎约为 256,这使我们怀疑某处可能存在位翻转(可能是符号位?)。然而,相同的十六进制转储表明情况并非如此。

这是错误的代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
unsigned char data_arr[2];
unsigned short data;
data=0;
int pixel_per_line=1024;
char path1[80]="source.IMG";
char path[80]="destination"
fp=fopen(path1,"rb");
bin=fopen(path,"wb");
//fp points to the input file, bin to the output file.
fseek(fp,8193,SEEK_SET);//sets the pointer to the relevant byte in the source file. 
//A similar fseek() is used on bin in the original program
while(!feof(fp))
{
//fflush(fp); (Removed the fflush()s now)
int j;
for(j=0;j<pixels_per_line;j++)//iterate through all pixels in one line
        {
        for(int i=0;i<2;i++)
            data_arr[i]=fgetc(fp);
        //data=(data_arr[0] << 8) | data_arr[1];// bit manipulations done in the earlier version. 
        //This fails to give the right output.
         data=data_arr[0]*256 + data_arr[1]; // This switches alternate bytes. 
        if(fwrite(&data,1,sizeof(data),bin)!=2) 
            printf("Write pains!");
        }
//fflush(bin);
}
}

编辑:

  1. 添加fopen()语句并删除fflush()进行测试,错误仍然存​​在。

  2. 添加了无符号短数据的声明

  3. 代码现在应该运行。

编辑

2 字节图像的问题已解决! 我所做的只是切换交替字节。查看更正后的代码。 我不确定为什么它有效。这是字节序问题吗?请注意,位移不起作用。

我现在对于四字节图像也遇到类似的问题。数据存储为 float 。我将字节 fread() 转换为 float ,对其进行缩放并将其转换为整数。结果同样是颗粒状的。用位移位排列字节并不能解决问题。

有人能解释一下吗?

最佳答案

小问题:

不要使用feof(fp),而是使用:

while (1) {
  ...
  int ch = fgetc(fp);
  if (ch == EOF) break;
  data_arr[0] = ch;
  ch = fgetc(fp);
  if (ch == EOF) break;
  data_arr[1] = ch; 

更大的问题: 我怀疑您的输入文件(尽管以“rb”打开)在您阅读时发生了变化。也许您没有独占锁。

关于c - 使用 fwrite() 写入某些字节时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24543734/

相关文章:

c - 访问不带参数的函数变量值

c - 如何运行 fread() 以固定大小的 block 提取数据

c - 在C中输入数组

Python 基础 - 从 API 请求数据并写入文件

c++ - 尝试使用 Win32 线程进行异步 I/O

c - 成功 open() 后,程序在 read() 上停止

java - 将一行替换为 RandomAccessFile

c++ - 如何在MIPS汇编程序中使用库?

c - 多个定义,即使我正在使用 extern 并包含守卫

c - 将文件中特定点的数字存储为 (x, y) 坐标