检查文件是否为空?

检查文件是否为空?

嗯,最明显的方法是使用\ifeof,但出于某种原因,我无法正确做到这一点。我写道

\newread\reader
\openin\reader=empty \relax
\ifeof\reader\message{empty}\else\message{not empty}\fi
\closein\reader
\openin\reader=notempty \relax
\ifeof\reader\message{empty}\else\message{not empty}\fi
\closein\reader

其中empty是一个空文件(大小为 0),notempty是一个非空文件。TeX 似乎认为这两个文件都不为空。

答案1

您可以用于\pdffilesize简单的存在/空测试:

\def\firstoftwo#1#2{#1}
\def\secondoftwo#1#2{#2}
\def\iffileexist#1{%
  \expandafter\ifx\expandafter&\pdffilesize{#1}&%
    \expandafter\secondoftwo
  \else
    \expandafter\firstoftwo
  \fi
}
\def\iffileempty#1{%
  \ifnum0\pdffilesize{#1}>0
    \expandafter\secondoftwo
  \else
    \expandafter\firstoftwo
  \fi
}
\def\test#1{%
  \iffileexist{#1}{File #1 exists}{File #1 doesn't exist}
  \iffileempty{#1}{File #1 is empty}{File #1 isn't empty}\par
}
\test{notexist}
\test{empty}
\test{nonempty}
\bye

为了获得更好的便携性,您应该选择pdftexcmds包裹这使得\pdf@filesizepdfTeX 和 LuaTeX 都可以使用。

答案2

仅当文件不存在时,打开文件后立即\ifeof返回 false。您尚未尝试读取任何内容,因此正式而言,文件结束标记尚未找到,即使在文件为空的情况下也是如此。因此,您应该尝试将文件中的某些内容读入宏,然后检查两者\ifeof以及您读入的宏。

\newread\reader

\def\eolmarker{\par}

\def\testifempty#1{%
\openin\reader=#1\relax
\ifeof\reader
    \message{^^J#1: doesn't exist^^J}%
\else
    \read\reader to \readmacro
    \ifeof\reader
        \ifx\readmacro\eolmarker
            \message{^^J#1: is empty^^J}%
        \else
            \message{^^J#1: is not empty^^J}%
        \fi
    \else
        \message{^^J#1: is not empty^^J}%
    \fi
\fi
\closein\reader
}

\testifempty{empty}%   File "empty" is empty
\testifempty{notempty}% File "notempty" is not empty 
\testifempty{doesnotexist}% File "doesnotexist" doesn't exist

\bye

运行使用:

rm -f empty doesnotexist
touch empty
echo "not empty" > notempty
pdflatex <abovecode>.tex

结果:

This is pdfTeX, Version 3.1415926-1.40.11 (TeX Live 2010)
 restricted \write18 enabled.
entering extended mode
(./f.tex 
empty: is empty

notempty: is not empty


doesnotexist: doesn't exists
 )
No pages of output.
Transcript written on f.log.

相关内容