Jump to content
  • Advertisement
Sign in to follow this  
grill8

Question about getting information about files in C++.

This topic is 3627 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have a question about getting information about files in C++. Question) Given a file path, I need to know if a file exists already, if it is of the proper format (writable) and if it has the proper extension (.txt). What is the best way to do this in C++? Note) The only way I can think of would be:
bool ProperFormat(std::string file_name)
{
	if(std::ifstream exists(file_name.c_str()))
	{
		if(std::ofstream writable(file_name.c_str(), std::ios::out))
		{
			size_t offset = file_name.rfind(".");
			if(offset != std::string::npos)
			{
				std::string extension = file_name.substr(offset);
				if(".txt" == extension)
				{
					return ( true );
				}
			}
		}
	}
	return ( false );
};


That seems clumsy and there should be a better way to do it. Is there? Jeremy [Edited by - grill8 on January 7, 2009 3:25:39 AM]

Share this post


Link to post
Share on other sites
Advertisement
Files are an OS-specific thing. C++ does not provide anything useful other than the ability to create I/O streams on files.

You need to either use calls from your OS support library (eg. stat() on POSIX systems) or use a portability layer like boost.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
Files are an OS-specific thing. C++ does not provide anything useful other than the ability to create I/O streams on files.

You need to either use calls from your OS support library (eg. stat() on POSIX systems) or use a portability layer like boost.


IMHO, using Boost.FileSystem would be sensible as it is being adopted (modulo some tweaks no doubt) by the C++ standard.

Share this post


Link to post
Share on other sites
Call my crazy, but I can't see any functions in boost::filesystem for determining if a file is writable or not.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Call my crazy, but I can't see any functions in boost::filesystem for determining if a file is writable or not.


You're crazy :) But I can't either. Suggestion retracted.

EDIT: On a more helpful note, the concept of "writable" isn't entirely portable. On UNIX there's just the "write permission".

On Windows there are individual permissions for append, write, delete, writing attributes and writing extended attributes so it depends on what you really want to do with the file. In fact, there's also a permission that specifies whether or not you can read permissions at all, so on Windows checking for "write permission" is much more fiddly than one would really like.

Share this post


Link to post
Share on other sites
Question)

Without using anything but C++, is there any better way than the one I listed above?

I tested it and it seems to work correctly.

It does seem clumsy though.

Jeremy

Share this post


Link to post
Share on other sites
Quote:
Original post by grill8
Without using anything but C++, is there any better way than the one I listed above?


Quote:
Original post by Bregma
Files are an OS-specific thing. C++ does not provide anything useful other than the ability to create I/O streams on files.


So: No.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Call my crazy, but I can't see any functions in boost::filesystem for determining if a file is writable or not.


That should give an answer (from 1.37):

boost/filesystem/operations.hpp : class file_status
// the internal representation is unspecified so that additional state
// information such as permissions can be added in the future; this
// implementation just uses status_type as the internal representation

Share this post


Link to post
Share on other sites
In terms of code cleanliness:

- Pass arguments of object type by const reference.

- 'return' is not a function; the thing to return does not require parentheses.

- The logic for the filename extension test can be simplified (or at least optimized to avoid making a temporary copy of string data; I suppose what is "simplest" here is a matter of personal opinion). You might also want to do that test first. (Alternatively, you could accept the file name without an extension, and append the extension locally.)

- Since you're obviously not opposed to early returns, *use them* to avoid deep nesting. Better yet, use logical AND/OR connectors.

- You don't need names for temporary objects (the file streams). The way you use the names to indicate the purpose is nice, but it would be even nicer to use named free functions to do the work. :)

- Specifying std::ios::out for an ostream is redundant.


bool file_exists(const std::string& name) {
return std::ifstream(name.c_str()).good();
}

bool file_writable(const std::string& name) {
return std::ofstream(name.c_str()).good();
}

bool string_ends_with(const std::string& base, const std::string& suffix) {
return suffix.size() <= base.size() &&
std::equal(suffix.rbegin(), suffix.rend(), base.rbegin());
}

bool valid_text_file(const std::string& name) {
return string_ends_with(name, ".txt") && file_exists(name) && file_writable(name);
}

Share this post


Link to post
Share on other sites
Hello,

All excellent advice. Thank you very much. If anyone has any additional input I would love to hear it.

Jeremy

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!