My suggestion is to take a "white list" approach, meaning don't try and filter out bad characters. Instead define what is OK. You can either reject the filename or filter it. If you want to filter it:
String name = s.replaceAll("\W+", "");
What this does is replaces any character that isn't a number, letter or underscore with nothing. Alternatively you could replace them with another character (like an underscore).
The problem is that if this is a shared directory then you don't want file name collision. Even if user storage areas are segregated by user you may end up with a colliding filename just by filtering out bad characters. The name a user put in is often useful if they ever want to download it too.
For this reason I tend to allow the user to enter what they want, store the filename based on a scheme of my own choosing (eg userId_fileId) and then store the user's filename in a database table. That way you can display it back to the user, store things how you want and you don't compromise security or wipe out other files.
You can also hash the file (eg MD5 hash) but then you can't list the files the user put in (not with a meaningful name anyway).
EDIT:Fixed regex for java
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…