简体   繁体   English

C中的文件I / O有哪些最佳实践?

[英]What are some best practices for file I/O in C?

I'm writing a fairly basic program for personal use but I really want to make sure I use good practices, especially if I decide to make it more robust later on or something. 我正在编写一个供个人使用的相当基本的程序,但我真的想确保我使用好的做法,特别是如果我决定让它在以后变得更强大或者某些东西。

For all intents and purposes, the program accepts some input files as arguments, opens them using fopen() read from the files, does stuff with that information, and then saves the output as a few different files in a subfolder. 对于所有意图和目的,程序接受一些输入文件作为参数,使用fopen()从文件读取打开它们,对该信息执行操作,然后将输出保存为子文件夹中的几个不同文件。 eg, if the program is in ~/program then the output files are saved in ~/program/csv/ 例如,如果程序在~/program则输出文件保存在~/program/csv/

I just output directly to the files, for example output = fopen("./csv/output.csv", "w"); 我只是直接输出到文件,例如output = fopen("./csv/output.csv", "w"); , print to it with fprintf(output,"%f,%f", data1, data2); ,用fprintf(output,"%f,%f", data1, data2);打印到它fprintf(output,"%f,%f", data1, data2); in a loop, and then close with fclose(output); 在循环中,然后用fclose(output);关闭fclose(output); and I just feel like that is bad practice. 而我觉得那是不好的做法。

Should I be saving it in a temp directory wile it's being written to and then moving it when it's finished? 我应该将它保存在临时目录中吗?它会被写入,然后在它完成时移动它? Should I be using more advanced file i/o libraries? 我应该使用更高级的文件i / o库吗? Am I just completely overthinking this? 我只是完全过分思考这个吗?

Best practices in my eyes: 我眼中的最佳做法:

  • Check every call to fopen, printf, puts, fprintf, fclose etc. for errors 检查每次调用fopen,printf,puts,fprintf,fclose等是否有错误
  • use getchar if you must, fread if you can 如果必须,请使用getchar,如果可以的话,请使用fread
  • use putchar if you must, fwrite if you can 如果必须的话,请使用putchar,如果可以,请使用
  • avoid arbitrary limits on input line length (might require malloc/realloc) 避免输入行长度的任意限制(可能需要malloc / realloc)
  • know when you need to open output files in binary mode 知道何时需要以二进制模式打开输出文件
  • use Standard C, forget conio.h :-) 使用标准C,忘记conio.h :-)
  • newlines belong at the end of a line, not at the beginning of some text, ie it is printf ("hello, world\\n"); 换行属于一行的末尾 ,而不是某些文本的开头,即它是printf ("hello, world\\n"); and not "\\nHello, world" like those mislead by the Mighty William H. often write to cope with the sillyness of their command shell. 并不是像"\\nHello, world"威廉·H·威廉·H "\\nHello, world"那样误导的"\\nHello, world" ,经常写下来应对他们命令外壳的愚蠢。
  • if you need more than 7bit ASCII, chose Unicode (the most common encoding is UTF-8 which is ASCII compatible). 如果您需要超过7位ASCII,请选择Unicode (最常见的编码是与ASCII兼容的UTF-8)。 It's the last encoding you'll ever need to learn. 这是你需要学习的最后一个编码。 Stay away from codepages and ISO-8859-*. 远离代码页和ISO-8859- *。

Am I just completely overthinking this? 我只是完全过分思考这个吗?

You are. 你是。 If the task's simple, don't make a complicated solution on purpose just because it feels "more professional". 如果任务很简单,不要因为感觉“更专业”而故意制定复杂的解决方案。 While you're a beginner, focus on code readability, it will facilitate your and others' lives. 虽然您是初学者,但专注于代码可读性,它将促进您和他人的生活。

It's fine. 没关系。 I/O is fully buffered by default with stdio file functions, so you won't be writing to the file with every single call of fprintf . 默认情况下,使用stdio文件函数对I / O进行完全缓冲,因此每次调用fprintf都不会写入文件。 In fact, in many cases, nothing will be written to it until you call fclose . 实际上,在很多情况下,在你调用fclose之前,不会写入任何内容。

It's good practice to check the return of fopen , to close your files when finished, etc. Let the OS and the compiler do their job in making the rest efficient, for simple programs like this. 最好检查fopen的返回,完成后关闭文件等等。让操作系统和编译器尽其所能地完成其余工作,对于像这样的简单程序。

If no other program is checking for the presence of ~/program/csv/output.csv for further processing, then what you're doing is just fine. 如果没有其他程序检查是否存在~/program/csv/output.csv进行进一步处理,那么你正在做的就好了。

Otherwise you can consider writing to a FILE * obtained by a call to tmpfile in stdio.h or some similar library call, and when finished copy the file to the final destination. 否则,您可以考虑写入通过调用stdio.h中的tmpfile或类似的库调用获得的FILE * ,并在完成时将文件复制到最终目标。 You could also put down a lock file output.csv.lck and remove that when you're done, but that depends on you being able to modify the other program's behaviour. 您还可以放下一个锁定文件output.csv.lck并在完成后删除它,但这取决于您是否能够修改其他程序的行为。

你可以制作自己的catcpmv程序进行练习。

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

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