嗯,最明显的方法是使用\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@filesize
pdfTeX 和 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.