I have two classes. SpeciesReader takes files and parses them. Species stores certain data about a species, which has been parsed from the file.
Currently, I have a method: SpeciesReader.generateSpecies(), which uses the file with which it was instantiated to create a Species object. Is this bad practice/design? Should I somehow find a way to move this to a constructor in Species that takes the filename as an argument?
Not at all. That’s a common pattern called a factory.
That being said, factories are usually implemented on the class itself (Species in this case) rather than a separate class but I see no problem with separating it like that.
As for whether this responsibility should go on Species instead, that depends on the nature of the files. If a file contains merely one Species and there’s no large overhead in loading that file then it might make sense to make it part of Species.
But if the file contains lots of species or is expensive to initialize then it makes perfect sense to move that responsibility to another class and have it be responsible for creating Species objects.