karluk's response was correct, an end of file condition will cause a no_data_found exception. mesuj's code won't quite work, because it doesn't handle the exception. Many people don't like this, so they write their own package to wrap UTL_FILE.GET_LINE and UTL_FILE.GET. My version turns GET_LINE into a function returning a BOOLEAN which is true if GET_LINE returned data, and FALSE at EOF.
FUNCTION GET_LINE (
file_handle IN UTL_FILE.FILE_TYPE,
line_out OUT VARCHAR2
) RETURN boolean;
BEGIN
UTL_FILE.GET_LINE(file_handle, line_out);
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN FALSE;
WHEN OTHERS THEN
RAISE;
END GET_LINE;
If my version of GET_LINE is in a package called IO, then the procedure that reads c:\docs\test.txt does:
fh UTL_FILE.FILE_TYPE;
line_read VARCHAR2(80);
BEGIN
fh := UTL_FILE.FOPEN('c:\docs','test.txt','r');
WHILE IO.GET_LINE(fh,line_read) LOOP
-- do stuff with line_read
END LOOP;
UTL_FILE.FCLOSE(fh);
EXCEPTION
-- It is a good idea to handle the other exceptions that
-- UTL_FILE might raise.
END;