# Checking whether a file is empty?

Well, the obvious way to do that is with \ifeof, but for some reason, I cannot do this right. I wrote

\newread\reader


where empty is an empty file (sized 0), and notempty is non-empty file. TeX seems to think that both files are not empty.

You can use \pdffilesize for simple existence/empty tests:

\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


For greater portability you should prefer the pdftexcmds package which makes \pdf@filesize available for both pdfTeX and LuaTeX.

• @Phillip: I think this carves around TeX annoyance in an elegant way. – Yossi Gil Feb 28 '11 at 7:46

Straight after opening a file \ifeof is false only when the file doesn't exist. You have not tried to read anything yet, so officially the end-of-file marker has not been found yet, even in the case where the file is empty. So you should try to read something from the file into a macro and then check both \ifeof and the macro you read into.

\newread\reader

\def\eolmarker{\par}

\def\testifempty#1{%
\message{^^J#1: doesn't exist^^J}%
\else
\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
}

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

\bye


## Run using:

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


## Result:

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.

• Thanks. It works. Take note that it also works if the non-empty file does not contain an eoln, i.e., if you produced with with echo -a " " > notempty. – Yossi Gil Feb 27 '11 at 20:49
• I must confess I think this behavior of TeX is a bit "clever" not say "ubersmart". – Yossi Gil Feb 27 '11 at 20:52
• How can I make this work for files in which braces are not balanced? – Hernan Nov 16 '13 at 14:04
• @Hernan: Then you need to disable the normal meaning of braces before reading from the file. You then need to wrap the code into a group (\begingroup, \endgroup) so that the change is not global. The code would be like \begingroup\let\do\@makeother\dospecials \read\reader to \readmacro \ifeof\reader\endgroup <then code> \else\endgroup <else code>\fi. You need to place \makeatletter before and \makeatother behind the macro definition then to allow macros with an @ symbol in them. See e.g. tex.stackexchange.com/a/38910/2975 for a similar example. – Martin Scharrer Nov 17 '13 at 16:25