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{%
\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
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.