Don't use ls if you want to get filenames, it does a bunch of stuff to them. Use a shell glob or find.
Also, because filenames can have newlines, if you want to loop over them, it's best to use one these:
for x in *; do do_stuff "$x"; done # can be any shell glob, not just *
find . -exec do_stuff {} \;
find . -print0 | xargs -0 do_stuff # not POSIX but widely supported
find . -print0 | xargs -0 -n1 do_stuff # same, but for single arg command
When reading newline-delimited stuff with while read, you want to use:
cat filenames.txt | while IFS= read -r x; do_stuff "$x"; done
The IFS= prevents trimming of whitespace, and -r prevents interpretation of backslashes.