繁体   English   中英

如何在不创建其他临时文件的情况下从文件中删除标头?

[英]How to remove a header from file without creating additional temporary files?

我正在开发一个运行Linux的嵌入式系统的应用程序。

就我而言,我有一个非常大的文件(与系统的功能相比)作为输入。 该文件有一个小标题,其大小只有几百字节。 在我的应用程序中,我需要从文件中删除该标头,以便该文件没有标头并仅包含相关数据。 通常,我实现如下(伪代码):

char *input_file  = "big_input.bin";
char *tmp_file1 = "header.bin";
char *tmp_file2 = "data.bin";
/* Copy the content of header from input file to tmp_file1 */ 
_copy_header(tmp_file1, input_file); 
/* Copy the data from input file to tmp_file2 */ 
_copy_data(tmp_file2, input_file);
/* Rename temp file to input file */
unlink(input_file);
rename(tmp_file2, input_file);

这种方法的问题在于它创建了一个临时文件tmp_file2其大小几乎与输入文件一样大(因为标头非常小)。 在我的系统中,一切都存储在RAM中,这是非常有限的。 创建大型临时文件会导致内存不足错误。

那么如何避免创建一个大的临时文件呢?

提前致谢!

打开同一个文件两次,一次用于读取,一次用于写入。

寻找标题后面的读指针。

从读指针读取并写入写指针。

确保一次读取和写入的大小不大于标题。

切断文件末尾的标题大小。

假设您事先知道标头的确切大小,这样的事情应该这样做:

#define HEADER_SIZE 128

// size the buffer as appropriate for you RAM limits
char buffer[ 4096 ];
int fd = open( filename, O_RDWR );
size_t totalBytes = 0UL;
for ( ;; )
{
    ssize_t bytes_read = pread( fd, buffer,
        sizeof( buffer ), totalBytes + HEADER_SIZE );
    if ( bytes_read <= 0L )
    {
        break;
    }
    pwrite( fd, buffer, bytes_read, totalBytes );
    total_bytes += bytes_read;
}

ftruncate( fd, total_bytes );

close( fd );

您需要添加正确的头文件和一些错误检查。

在你的情况下,你可以

  • 以读写方式打开文件
  • 从你的偏移读取char-by-char并写入开头,循环直到文件结尾(听起来不是最理想但是你在RAM驱动器上,而且很简单。更快的方法意味着读取更多字节,可能更复杂地实现,必须测量速度增益)
  • 最后,您可以使用truncateftruncate截断文件,如下所述: 如何截断C中的文件?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM