65.9K
CodeProject 正在变化。 阅读更多。
Home

转储 Windows 中的文件

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.50/5 (5投票s)

2005年11月15日

CPOL

2分钟阅读

viewsIcon

35383

downloadIcon

201

这个程序可以在 Windows 中将文件转储到标准输出。

引言

这个程序可以将文件(无论是二进制文件还是文本文件)转储到 Windows 中的 DOS 窗口中的标准输出。它是 Unix/Linux 中著名的 od 程序的 Windows 版本。它也是一个免费程序,实现了一个类似于 Windows 中 UltraEdit 的主函数。它可以以 10 种不同的数据类型转储文件。

实现

这是一个简单的 C 程序,包含两个子程序:wod.cdump2stdout.c。主程序 wod.c 主要获取用户输入参数(转储数据类型)和文件中的字符流。然后,它将这些参数传递给子程序 dump2stdout.c。它从头文件 wod.h 中获取预定义的数据类型,该文件是一个 enum 数据结构,如下所示

Enum { OD_CHAR, OD_SHORT_INT, OD_LONG, OD_D_CHAR, OD_D_SHORT, 
       OD_D_LONG, OD_ASCII, OD_BIN, OD_FLOAT, OD_DOUBLE } ;

为了潜在的改进,主程序将整个文件分成固定长度的段和一个尾段

Fixed segment length : blk_size = 1024 ( bytes )
Tail segment length  : tail_len = file_len % blk_size ;
Segments count       : blk_no   = file_len / blk_size ;

wod.c 中有一个奇怪的 "tell(fd)"。我知道 "read" 应该将文件指针向前移动一个字节,但似乎它并不总是起作用,所以我在这里添加了这个冗余函数。为了在不同的数据类型之间转换,我在 wod.h 中定义了一个 UNION 数据结构,如下所示

Union buf_union {

    unsigned char ubuf [ MAX_BLOCK_SIZE ] ;
    unsigned short int sint [ MAX_BLOCK_SIZE / 2 ] ;
    unsigned long lint [ MAX_BLOCK_SIZE / 4 ] ;
    float ieeef [ MAX_BLOCK_SIZE / 4 ] ;
    double ieeed [ MAX_BLOCK_SIZE / 8 ] ;

} ;

在子程序 dump2stdout.c 中,tmpc[16] 用作转储二进制时的位掩码,而 asc_buf[16] 用于存储一行中的临时 ASCII 字符串。它是转储 ASCII 最流行和最有用的函数。ASCII 转储有三列。第一列是十六进制地址列,第二列是十六进制字符列,第三列是 ASCII 字符。变量 start_poi 是每个段的起始偏移位置。

case OD_ASCII:

    for ( i = 0 ; i < block_size ; i++ ) {
        if ( i % 16 == 0 ) {
            j = 0 ;  // initialize asc_buf counter j
            if ( i > 0 ) printf ( "  %.16s\n", asc_buf ) ;
            // print 16 ASCII characters
                printf ( "%.8X: ", i + start_poi ) ;
                // print HEX offset address
            
            memset ( asc_buf, '\0', sizeof ( asc_buf ) ) ;
            // clean buffer for asc_buf
        }

        printf ( "%.2x ", buf [ i ] ) ;
        // print 16 HEX characters

        if ( buf [ i ] >= 0x7F || buf [ i ] < 0x20 )
            buf [ i ] = '.' ;
            // print non-printable characters as "."

        asc_buf [ j++ ] = buf [ i ] ;
        // get ASCII value
    }

    l = strlen ( ( const char * ) asc_buf ) ;
    // real length of the last asc_buf

    if ( l < 16 ) {
        for ( m = 0 ; m < 3 * ( 16 - l ) ; m++ ) printf (" ") ;
        // supplement spaces for the last line
    }

    printf ( "  %.16s", asc_buf ) ;
    // print the last ASCII string

    //printf ( "\n%.8X: ", i + start_poi ) ;
    // print separated segment offset if you like
   
    break ;

编译

这个程序在 Windows XP 中的 MinGW 环境中编译。您必须设置 PATH 环境变量,或者在编译之前运行 setp.bat

set PATH = %PATH%; C:\MinGW\bin ;

然后,运行 ccm.bat,或者手动编译程序如下

g++ -c dump2stdout.c

g++ -c wod.c

g++ wod.o dump2stdout.o -o wod.exe

最后,您可以在 DOS 窗口中运行该程序。为了方便起见,您可以将输出重定向到文本文件,如下所示

wod test.dat > test.txt

改进问题

  1. 这个纯 C 程序易于移植到不同的平台。
  2. 您可以修改主文件 wod.c 以使该程序更灵活。例如,您可以添加一些运行时参数作为位置控制参数,例如起始位置和结束位置。
  3. 您可以将程序输出到文本文件,方法是将 "printf" 替换为 "fprintf"。
  4. 您可以尝试使用 "lseek64" 和 "__off64_t" 或类似函数来使程序支持大文件。
  5. 如果您是一位顽固的 Windows 风格程序员,您可以开发一个 GUI 来包装这个小程序。
© . All rights reserved.