将struct存储到文件并再次检索它

时间:2012-12-28 17:42:48

标签: c

我有一个结构

typedef struct esl_sqfile_s {
  FILE *fp;           /* Open file ptr                            */
  char *filename;         /* Name of file (for diagnostics)           */
  int   do_gzip;          /* TRUE if we're reading from gzip -dc pipe */
  int   do_stdin;         /* TRUE if we're reading from stdin         */
  char  errbuf[eslERRBUFSIZE];/* parse error mesg. Size must match msa.h  */

  /* all input first gets buffered in memory; this gives us enough
   * recall to use Guess*() functions even in nonrewindable streams
   */
  char    *mem;           /* buffered input                           */
  int      allocm;        /* <mem> size, multiples of eslREADBUFSIZE  */
  int      mn;            /* number of chars in <mem> (up to allocm)  */
  int      mpos;          /* pos of next <buf> to load from <mem>     */
  off_t    moff;          /* disk offset to start of <mem>            */
  int      is_recording;      /* TRUE if we need to keep buffering more   */

  /* input is either character-based [fread()] or line-based (esl_fgets())*/
  char    *buf;           /* buffer for fread() or fgets() input      */
  off_t    boff;          /* disk offset to start of buffer           */
  int      balloc;        /* allocated size of buf                    */
  int      nc;            /* #chars in buf (usually full, less at EOF)*/ 
  int      bpos;          /* current position in the buffer (0..nc-1) */
  int64_t  L;             /* #residues seen so far in current seq     */
  int64_t  linenumber;        /* What line of the file  (1..N; -1=unknown)*/
  off_t    bookmark_offset;   /* bookmark fwd position before reversing...*/
  int64_t  bookmark_linenum;  /* in both linenumber and disk offset       */

  /* In digital mode, we have an alphabet ptr                             */
  int   do_digital;       /* TRUE if we're reading in digital mode    */
#if defined(eslAUGMENT_ALPHABET)  
  const ESL_ALPHABET *abc;
#else
  void               *abc;
#endif

  /* Format-specific configuration                                           */
  int   format;           /* Format code of this file                    */
  int   is_linebased;         /* TRUE for fgets() parsers; FALSE for fread() */
  int   eof_is_ok;        /* TRUE if record can end on EOF               */
  int  (*parse_header)(struct esl_sqfile_s *, ESL_SQ *sq);
  int  (*parse_end)   (struct esl_sqfile_s *, ESL_SQ *sq); 
  ESL_DSQ inmap[128];         /* an input map, 0..127                        */

  /* MSA augmentation confers reading MSA files as sequential seq files. */
#if defined(eslAUGMENT_MSA)
  ESL_MSAFILE *afp;       /* open ESL_MSAFILE for reading           */
  ESL_MSA     *msa;       /* preloaded alignment to draw seqs from  */
  int          idx;       /* index of next seq to return, 0..nseq-1 */
#else
  void        *afp;           /* NULL */
  void        *msa;           /* NULL */
  int          idx;           /* 0    */
#endif /*eslAUGMENT_MSA*/

  /* SSI augmentation confers random access of records in a seq file        */
  char    *ssifile;       /* path to expected SSI index file            */
  int      rpl;           /* residues per line in file; -1=unset 0=inval*/
  int      bpl;           /* bytes per line in file; -1=unset, 0=inval  */
  int      currpl;        /* residues on current line (-1=unknown)      */
  int      curbpl;        /* bytes on current line    (-1=unknown)      */
  int      prvrpl;        /* residues on previous line                  */
  int      prvbpl;        /* bytes on previous line                     */
#if defined(eslAUGMENT_SSI)
  ESL_SSI *ssi;     /* open ESL_SSI index, or NULL if none     */
#else
  void    *ssi;     /* NULL */
#endif /*eslAUGMENT_SSI*/
} ESL_SQFILE;

我想将struct值存储到文件中并在需要时读取它。问题是,如果我编写整个结构的某些值将包含地址而不是值。有没有解决这个问题的方法

4 个答案:

答案 0 :(得分:3)

  

如果我编写整个结构的某些值将包含的问题   地址而不是价值。有没有解决这个问题的方法

唯一真正的解决方案是手动将结构的每个成员写入文件。即定义你自己的pack函数,为每个成员做正确的事。

答案 1 :(得分:2)

您还必须存储指针指向的数据。没有其他解决方案可以满足您的需求。

答案 2 :(得分:2)

正如您所发现的,您无法有效地存储指向磁盘的指针。当您尝试加载数据时,指针值将毫无意义,您需要正确序列化数据。

外部表示(针对存储和/或通信进行了优化的外部表示)与最佳内部表示不同,这是最典型的,内部表示针对程序实际使用进行了优化。

在C中,期望将整个结构体保存/加载为单位也是一个坏主意,因为在字段之间可能存在编译器添加的“不可见”填充字节。如果您在此期间切换了编译器,编译器标志或计算机,这可能导致结构无法在程序的未来版本中加载。

最好编写一个函数来保存结构,然后编写一个函数来加载它,然后让它们逐个字段地遍历结构,并进行必要的转换以使每个字段与其首选的外部表示形式相同。

如果你需要做很多事情,有一些“中间件”解决方案可以让你用特定于域的语言定义你的结构,然后生成代码来进行保存/加载和运行时管理。

答案 3 :(得分:1)

如果你能发挥你的想象力去寻找序列化机制。有趣的是,想象一下如何将它存储在XML类型的结构化文件中,以及如何使用字典来保存与原始数据类型的对应关系。