Pro Spring is a superb introduction to the world of Inversion of Control and Dependency Injection. If you're not aware of these practices and their implications - the balance of topics and technical detail in Pro Spring is excellent. It builds a great case and consequent personal foundation.
Another book I'd suggest would be Robert Martin's Agile Software Development (ASD). Code smells, agile techniques, test driven dev, principles ... a well-written balance of many different programming facets.
More traditional classics would include the infamous GoF Design Patterns, Bertrand Meyer's Object Oriented Software Construction, Booch's Object Oriented Analysis and Design, Scott Meyer's "Effective C++'" series and a lesser known book I enjoyed by Gunderloy, Coder to Developer.
And while books are nice ... don't forget radio!
... let me add one more thing. If you haven't already discovered safari - take a look. It is more addictive than stack overflow :-) I've found that with my google type habits - I need the more expensive subscription so I can look at any book at any time - but I'd recommend the trial to anyone even remotely interested.
(ah yes, a little obj-C today, cocoa tomorrow, patterns? soa? what was that example in that cookbook? What did Steve say in the second edition? Should I buy this book? ... a subscription like this is great if you'd like some continuity and context to what you're googling ...)
I liked these books:
You should also read code. If the code is hard to read, ask yourself what exactly the author did or didn't do that makes it hard to understand, and more importantly, how you can use what you've learned to write better code yourself.
Loosely coupling is beneficial in all circumstances, but you should also be aware of the additional complexity it may introduce. If you apply the Dependency Inversion principle (read Robert C. Martin's book on Agile Principles for an excellent discussion), you might consider the File.IO library to define an abstraction (e.g. an interface) that it needs for logging. You can then provide an implementation of that abstraction using your preferred logging library. To be clear, that's not the same as using the abstraction offered by the logging library in the File.IO library. Then you would still be locking them together.
One of the most influential programming books I've ever read. The code is in Java, but it's east to follow even for a non-Java developer, and the truths are universal. Learn the most fundamental design and encapsulation patterns. Uncle Bob Martin is a legend. This book has probably made me tens of thousands of dollars.