I think the best way to have a salt is not to randomly generate one or store a fixed one. Often more than just a password is saved, so use the extra data. Use things like the username, signup date, user ID, anything which is saved in the same table. That way you save on space used by not storing the salt for each user.
Although your method can always be broken if the hacker gets access to your database AND your file, you can make it more difficult. Use different user data depending on random things, the code doesn't need to make sense, just produce the same result each time. For example:
if ((asc(username character 5) > asc(username character 2))
{
if (month the account created > 6)
salt = ddmmyyyy of account created date
else
salt = yyyyddmm of account created date
}
else
{
if (day of account created > 15)
salt = user id * asc(username character 3)
else
salt = user id + asc(username character 1) + asc(username character 4)
}
This wont prevent them from reading passwords when they have both database and file access, but it will confuse them and slow them up without much more processing power required to create a random salt