📄 faqcatea63.html
字号:
(If you have the choice,the best compromiseis probably one of the <TT>stat</TT> functions.)</p><p>Rather than trying to predict in advancewhether an operationsuch as opening a filewill succeed,it's often better totry it,check the return value,and complain if itfails.(Obviously, this approach won't workif you're trying to avoid overwriting anexisting file, unless you've got something like the<TT>O_EXCL</TT>file openingoption available,which does just what you wantinthiscase.)</p><p>References:PCS Sec. 12 pp. 189,213<br>POSIX Sec. 5.3.1, Sec. 5.6.2, Sec. 5.6.3<hr><hr><hr><a name="filesize"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/filesize.html"><!-- qtag -->Question 19.12</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I find out the size of a file,prior to reading it in?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>If the ``size of a file''is the number of characters you'll be able to read from itin C(or which were written to it by a previous program),itcan bedifficultorimpossibleto determine this numberexactly(other thanby reading the whole file).</p><p>UnderUnix,the <TT>stat</TT> call(specifically,the <TT>st_size</TT> field of the stat structure)will give you an exact answer.<a href="../../osdep/concur2.html" rel=subdocument>[footnote]</a>Several other systems supply aUnix-like<TT>stat</TT>call,but the sizes reported for text filesmay be approximate(due to differing end-of-line representations;see question <a href="faqcat1d60.html?sec=stdio#textvsbinary">12.40</a>).You canopen the file and use <TT>fstat</TT>,or<TT>fseek</TT> to the endof the fileand then use <TT>ftell</TT>,butthese tend to havethe sameproblems:<TT>fstat</TT> is not portable,and generally tells you the same thing <TT>stat</TT> tells you;<TT>ftell</TT> is not guaranteed to return a byte countexcept for binary files(but,strictly speaking,binary files don't necessarily support <TT>fseek</TT> to <TT>SEEK_END</TT>at all).Some systemsprovide functions called<TT>filesize</TT>or <TT>filelength</TT>,but these are obviously not portable, either.</p><p>Are you sure you have to determine the file's size in advance?Since the most accurate way of determining the size of a file asa C program will see it is toopen the fileand read it,perhaps you can rearrange the code to learn the size as it reads.(In general, your programshould behavegracefullyifthenumber of charactersactuallyreaddoes notmatchprior expectations,since any advance determination of the size might be approximate.)See also questions<a href="faqcatbafd.html?sec=malloc#realloc">7.29</a>,<a href="faqcatbafd.html?sec=malloc#reallocnull">7.30</a>,and <a href="faqcat38c2.html?sec=misc#ragged">20.2</a>.</p><p>Additional links:<a href="../../osdep/sd23.html" rel=subdocument>further reading</a></p><p>References:ISO Sec. 7.9.9.4<br>H&S Sec. 15.5.1<br>PCS Sec. 12 p. 213<br>POSIX Sec. 5.6.2<hr><hr><hr><a name="modtime"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/modtime.html"><!-- qtag -->Question 19.12b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I find the modification dateand timeof a file?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The Unix and POSIX function is <TT>stat</TT>,which several other systems supply as well.(See also question <a href="faqcatea63.html?sec=osdep#filesize">19.12</a>.)<hr><hr><hr><a name="ftruncate"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/ftruncate.html"><!-- qtag -->Question 19.13</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can a file be shortened in-place without completely clearingor rewriting it?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>BSD systems provide <TT>ftruncate</TT>,several others supply <TT>chsize</TT>,and a few may provide a(possibly undocumented)<TT>fcntl</TT> optionF_FREESP.Under MS-DOS,you can sometimes use <TT>write(fd, "", 0)</TT>.However,there is no portable solution,nor a way to delete blocks at the beginningor in the middle.See also question <a href="faqcatea63.html?sec=osdep#insdelrec">19.14</a>.<hr><hr><hr><a name="insdelrec"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/insdelrec.html"><!-- qtag -->Question 19.14</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I insert or delete a line(or record)in the middle of a file?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>In general, there is no way todo this.<a href="../../osdep/nonseq.html" rel=subdocument>[footnote]</a>The usual solution is simply to rewrite the file.</p><p>When you find yourself needing to insert datainto an existing file,here are a few alternatives you can try:</p><UL><li>Rearrange the data file so that you can append the new information at the end.<li>Put the information in a second file.<li>Leave some blank space(e.g. a line of 80 spaces,or a field like <TT>0000000000</TT>)in the file when it is first written,and overwrite itlaterwith the finalinformation(see also question <a href="faqcat1d60.html?sec=stdio#fupdate">12.30</a>).(This technique is most portable in binary mode;on some systems,overwriting a text file may truncate it.)<li>Use a databaseinstead of a flat file.</UL><p>Instead of actually deleting records,you might considerjust marking them as deleted,and having the code which reads the file ignore them.(You could run a separatecoalescionprogram once in a whileto rewrite the file,finallydiscardingthe deleted records.Or,if the records are all the same length,you could take the last recordand use it to overwrite the record to be deleted,then truncate the file.)</p><p>See also questions<a href="faqcat1d60.html?sec=stdio#fupdate">12.30</a>and<a href="faqcatea63.html?sec=osdep#ftruncate">19.13</a>.</p><p>Additional links:<a href="../../osdep/insertf.20000216.html">further reading</a><hr><hr><hr><a name="fdfilename"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/fdfilename.html"><!-- qtag -->Question 19.15</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I recover the file name given an openstreamorfile descriptor?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>This problem is, in general, insoluble.UnderUnix,for instance,a scan of the entire disk(perhaps involving special permissions)would theoretically be required,and would fail if thedescriptorwereconnected to a pipeor referred to a deleted file(andcould give a misleading answer for a file with multiple links).It is best to rememberthe namesof files yourselfasyou open them(perhaps witha wrapper function around<TT>fopen</TT>).<hr><hr><hr><a name="delete"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/delete.html"><!-- qtag -->Question 19.16</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I delete a file?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The Standard C Library function is<TT>remove</TT>.(This is therefore one of the few questions in this sectionfor which the answer is <em>not</em>``It's system-dependent.'')On older,pre-ANSIUnix systems,<TT>remove</TT> may not exist,in which case you can try<TT>unlink</TT>.<a href="../../osdep/unlink.html" rel=subdocument>[footnote]</a></p><p>References:K&R2 Sec. B1.1 p. 242<br>ISO Sec. 7.9.4.1<br>H&S Sec. 15.15 p. 382<br>PCS Sec. 12 pp. 208,220-221<br>POSIX Sec. 5.5.1, Sec. 8.2.4<hr><hr><hr><a name="copy"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/copy.html"><!-- qtag -->Question 19.16b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How do I copy files?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Either use <TT>system()</TT>to invoke your operating system's copy utility(see question <a href="faqcatea63.html?sec=osdep#system">19.27</a>),or openthe source and destination files(using <TT>fopen</TT> or some lower-level file-opening system call),read characters or blocks of characters from the source file,and write them to the destination file.Here is a simple example:<pre>#include <stdio.h>int copyfile(char *fromfile, char *tofile){ FILE *ifp, *ofp; int c; if((ifp = fopen(fromfile, "r")) == NULL) return -1; if((ofp = fopen(tofile, "w")) == NULL) { fclose(ifp); return -1; } while((c = getc(ifp)) != EOF) putc(c, ofp); fclose(ifp); fclose(ofp); return 0;}</pre>To copy a block at a time, rewrite the inner loop as<pre> while((r = fread(buf, 1, sizeof(buf), ifp)) > 0) fwrite(buf, 1, r, ofp);</pre>where <TT>r</TT> is an <TT>int</TT>and <TT>buf</TT> is a suitably-sized array of <TT>char</TT>.</p><p>References:K&R Sec. 1, Sec. 7<hr><hr><hr><a name="dospath"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/dospath.html"><!-- qtag -->Question 19.17</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why can't I open a file by its explicit path?Thecall<pre>fopen("c:\newdir\file.dat", "r")</pre>is failing.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The file you actually requested--withthe characters <TT>\n</TT> and <TT>\f</TT> in itsname--probablydoesn't exist,and isn't what you thought you were trying to open.</p><p>In character constants and string literals,the backslash <TT>\</TT> is an escape character,giving special meaning to the character following it.In orderforliteral backslashes ina pathname tobepassed through to <TT>fopen</TT>(or any other function)correctly,they have to be doubled,so that the firstbackslash in each pairquotes the second one:<pre> fopen("c:\\newdir\\file.dat", "r")</pre>Alternatively,under MS-DOS,it turns out thatforward slashes are also accepted as directory separators,so you could use<pre> fopen("c:/newdir/file.dat", "r")</pre>(Note, by the way, thatheader file namesmentioned inpreprocessor <TT>#include</TT> directivesare <em>not</em> string literals,so you may not have to worry about backslashes there.)<hr><hr><hr><a name="fopenenv"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/fopenenv.html"><!-- qtag -->Question 19.17b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font><TT>fopen</TT> isn't letting me open files like<TT>"$HOME/.profile"</TT>and<TT>"~/.myrcfile"</TT>.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Under Unix, at least,environment variables like <TT>$HOME</TT>,along with the home-directory notation involving the <TT>~</TT> character,are expanded by the shell,and there's no mechanism to perform these expansionsautomatically when you call <TT>fopen</TT>.<hr><hr><hr><a name="abrtretrign"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/abrtretrign.html"><!-- qtag -->Question 19.17c</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I suppress thedreaded MS-DOS``Abort, Retry, Ignore?'' message?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Among other things,you need to intercept the DOS Critical Error Interrupt,interrupt 24H.See the comp.os.msdos.programmer FAQ listfor more details.<hr><hr><hr><a name="nfile"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/nfile.html"><!-- qtag -->Question 19.18</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm getting an error,``Too many open files''.How can I increase the allowable number of simultaneously open files?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>There are typicallyat leasttwo resource limitations on the number of simultaneously open files:the number of low-level ``file descriptors'' or ``file handles'' available in the operating system, and the number of <TT>FILE</TT> structures available in the stdio library.Both must be sufficient.Under MS-DOS systems,you can control the number of operating system file handles with a line in CONFIG.SYS.Some compilers come with instructions (and perhaps a source file or two) for increasing the number of stdio <TT>FILE</TT> structures.</p><p>Additional links:<a href="../../osdep/sd24.html" rel=subdocument>further reading</a><hr><hr><hr><a name="diskfree"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../osdep/diskfree.html"><!-- qtag -->Question 19.19</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I find out how much free spaceis available on disk?</p><p><hr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -