I have a requirement for reading, updating and deleting a file. I want to write a class for this.
For example
class FileManagement {
private:
fstream myFile;
public:
void read();
void update();
void delete();
};
My question is while updating is it possible to delete only one line in a file in C++ and should be portable, if it is possible how we can achieve this.
Other question is if above option is not possible how we can achieve the above.
In C++ how we can delete a file in portable way.
Thanks!
Use standard C/C++ functions fopen(), fread(), fwrite(), rename() and remove() for that. http://www.cplusplus.com/reference/clibrary/cstdio/
I recommend Boost Filesystem.
Its description reads:
"The Boost Filesystem Library provides portable facilities to query and manipulate paths, files, and directories."
You appear to be asking two different questions at once, in a confusing way.
To delete a file, use the remove function, found in stdio.h.
To erase one line of a file, you have to read the entire file and write it back out with the line removed. There is no library routine for this. The standard "safe" technique is to read the entire file, write it back out (with the line you don't want removed) to a new file in the same directory, fsync the new file, close it, then rename the new file to the old name. If you don't care about concurrent readers or the computer crashing in the middle of the operation, you can instead open the old file read/write, read its contents into memory, rewind the file handle, and rewrite it directly.
You should look at the posix standard, and find the file operations (like fopen()). Where platforms do not support posix, or diverge from the standard, you'll likely need to
#ifdef NONPOSIXOS1 // really, this should be a good identifier of hte OS
// write code to handle the special case
#else
// write code to handle the posix compliant case
#endif
Most systems will accept posix compliant statements. You could always just define abstract base class and create different concrete implementations that use whatever platform specific instructions you need. You could have one if def that instantiates the correct concrete class.
If you are looking for a higher-level C++ library that is object-oriented and can handle both filename manipulation and file I/O, POCO is a decent choice:
http://pocoproject.org
ACE is an older, battle-tested framework that includes lots of I/O support. It's commonly used for it's excellent CORBA support, but there's a lot in there:
http://www.cs.wustl.edu/~schmidt/ACE-overview.html
And, finally, there's QT. Normally known for its cross-platform UI library, QT actually includes several other useful pieces (including file management and I/O), and you don't even have to link in the UI stuff if you don't need it.
http://qt.nokia.com/
If you'd rather not bring in another framework, I would recommend rolling your own File I/O classes using boost::filesystem and either the standard iostream or stdio functions. You can use the interfaces in the above frameworks as a reference, but you will also want to familiarize yourself with modern C++ design, as demonstrated by Boost and explained in Modern C++ Design.
Related
Is there a similar function to Turbo Pascal's assign(out f:file, const Name) function which assigns a name to a file in c++ without opening the file?
Pascal has an older language construct where you “bind” identifiers to external system resources. Borland (Turbo Pascal) never really implemented the concept beyond what you find in the file access routines.
Most modern languages follow the C-style methodology, in large part because almost all modern operating systems follow the Unix-style file/character device/etc design.
Either way, ask yourself what exactly you are trying to accomplish, then figure out how to do it using idiomatic C++. The C++ way really is more straightforward.
As you can see, C++ does not have a way in the standard library to create a file stream, give it a file name and then open it. The open action uses a file name.
You can create an file stream that is not open yet, but it won't have a file name.
I'm planning to write a programm which has to access to a certain file many times in r/w.
So I decided to use fstream, since I can use this class for both reading and writing purpose.
My idea is to open the file at the startup of the application and then close it as the application is closed too.
Since the file can be arbitrarily big, I was planning to use a "paging" structure, in which:
1) preallocate a fixed amount of memory for each page and a fixed number of page
2) load part of the file in to the first free page
3) if there is no free page, I select one non empty with a certain criterion, I commit all edit in it (if there are any) and then load the part of file in the page.
That's not so hard to code. But I was wondering If I'm going to reinvent the wheel... maybe the fstream itself is written in a smart way so that it also implements a similar paging mechanism. In that case, I would not take care about, just write and read at any time.
Some suggestion?
Don't do this by yourself. Unless you are using very exotic implementation, the fstream class already implement such a mechanism efficiently.
Checkout http://www.cplusplus.com/doc/tutorial/files/ "Buffers and Synchronization"
There are possible issues if you are seek-ing into file larger than 2GB with a old kernel or implementation of the standard library. Check this
Large file support in C++
or use Boost.Filesystem
Internal working of the standard C++ library vary by implementation. Hence a test would be needed to get some real data on your preferred platform. Generally memory mapped files are considered to be the fastest way to access data stored in a file (as Uflex has mentioned in his comment, but it has some drawbacks as well (see the linked wiki page). You can either use the standard (POSIX) C functions mmap() and munmap(), or the Boost C++ libraries which also have a portable C++ interface for memory mapped files.
CreateFile vs fopen vs ofsteam - advantage & disadvantage?
I heard that CreateFile powerful but only for windows.
Can you tell what should I use ( on windows) and why?
It depends on what you're doing. For sequentially reading and writing text files, iostream is definitely the way to go. For anything involving transactional security or non-standard devices, you'll have to access the system directly (CreateFile or open). Even then, for sequential reading and writing of text, the best solution is to define your own streambuf, and use that with iostream.
I can't think of any context where fopen would be preferable.
Unless you need the features provided by the Windows file functions (e.g. overlapped I/O) then my suggestion is going with either iostreams in C++ or FILE (fopen and friends) in C.
Besides being more portable, you can also use formated input/output for text files, and for C++ it's easy to overload the output/input operators for your classes.
If you want to use Windows file memory mapping you should use CreateFile (e.g. the HANDLE passed to CreateFileMapping API is the return value of CreateFile). Moreover, CreateFile offers higher customization options than C and C++ standard file API.
However, if you want to write portable code, or if you don't need Windows-specific features, C and C++ standard file APIs are just fine.
In some tests, when processing large data, I noted some performance overhead of C++ I/O streams vs. raw C file API; if you happen to be in cases like this, you could simply wrap raw C file API in some C++ RAII class, and still use it in C++ code.
Unless you absoulutely need the extra functionality provided by OS API functions (like CreateFile) I'd reccommend using the standard library functions (like fopen or ofstream). This way your program will be more portable.
The only real advantage of using CreateFile that I can think of is overlapped I/O and maybe finer grained access rights.
In most cases you will be better of using fopen in C or ofstream in C++. CreateFile gives some extra control over sharing and caching but does not provide formatting functionality.
I copied my answer from
fopen or CreateFile in Windows
which was closed for some reason which escapes me...
There is no defined way for fopen() to return the system error code. There might be an undefined way to access errno, but this might or might not be identical with the system error code.
Also, I don't think that there is an defined way to access the real system handle (of type HANDLE) which in turn you might want to use to pass on to one of the many win64 system calls which expect such a system handle (e.g. memory mapped IO)
Using open() an integer represents the file handle, which is not the system handle (on windows).
fopen() does not throw an exception in case of error. In order to have some RAII you would need to wrap it into a class.
Wrapping CreateFile() into a class, is not more expensive than wrapping fopen() or open() into a class.
Using the C++ feature (std::ofstream, std::ifstream) to write/read to/from files suffers from the same problem as fopen():
It does not throw by default on error. In order to enable this feature you need to call some method instead of being able to use some constructor argument -- means for RAII you would need to derive this class (in order to use it as a member/base class which throws on error).
It is undefined if one is able to retrieve the system error code from the exception thrown or if the message returned from what() tells you anything about the system error.
Using this stream interface there is no real pluggable interface to define the source or destination of reading from or writing to. Overloading the stream interface is quite cumbersome and error prone.
Using C like programming (paying attention to or ignoring return codes and manually writing cleanup code) is the source of much evil (remember heart-bleed?)...
Conclusions:
write a resource wrapper for CreateFile()/CloseHandle(). Resource wrapper is a class, which performs the do-action in the constructor and the undo-action in the destructor and throws an exception in case of error. There are many such pairs of system calls in every OS but especially in Win64.
Write a system error exception class (to be used for the above class in case of CreateFile() fails and for all the other system errors) or investigate, what the new system_exception class (in C++0x) is actually doing and if it is sufficient.
write a functional wrapper for ReadFile() and WriteFile() which converts a system error into a system exception object thrown...
Potentially define your own interface to write to somewhere and read from somewhere so that you can implement other things independent from the type of source/destination to read from/write to.
Writing a cache class which allows you to cache reading from somewhere or writing to somewhere is also child play. Of course the cache class should not know nor care about the source/destination you're writing to/reading from.
Don't be scared about these small tasks. You will actually know, what is happening in your code and these little pieces of code should be negligible (in amount of lines of code) compared to the code calling it. Also if you're using RAII for everything, the code calling into these utility classes, will be considerable less compared to when not using RAII and having to use two- or even more-step initialization and considerable less error prone. Replacing these utility classes with equivalent utility classes for other OS is also child play (using open()/close()/read()/write() on UNIXs).
And for the sake of the previous millennia don't read the google programming guidelines!
I know many have asked this question before, but as far as I can see, there's no clear answer that helps C++ beginners. So, here's my question (or request if you like),
Say I'm writing a C++ code using Xcode or any text editor, and I want to use some of the tools provided in another C++ program. For instance, an executable. So, how can I call that executable file in my code?
Also, can I exploit other functions/objects/classes provided in a C++ program and use them in my C++ code via this calling technique? Or is it just executables that I can call?
I hope someone could provide a clear answer that beginners can absorb.. :p
So, how can I call that executable file in my code?
The easiest way is to use system(). For example, if the executable is called tool, then:
system( "tool" );
However, there are a lot of caveats with this technique. This call just asks the operating system to do something, but each operating system can understand or answer the same command differently.
For example:
system( "pause" );
...will work in Windows, stopping the exectuion, but not in other operating systems. Also, the rules regarding spaces inside the path to the file are different. Finally, even the separator bar can be different ('\' for windows only).
And can I also exploit other functions/objects/classes... from a c++
and use them in my c++ code via this calling technique?
Not really. If you want to use clases or functions created by others, you will have to get the source code for them and compile them with your program. This is probably one of the easiest ways to do it, provided that source code is small enough.
Many times, people creates libraries, which are collections of useful classes and/or functions. If the library is distributed in binary form, then you'll need the dll file (or equivalent for other OS's), and a header file describing the classes and functions provided y the library. This is a rich source of frustration for C++ programmers, since even libraries created with different compilers in the same operating system are potentially incompatible. That's why many times libraries are distributed in source code form, with a list of instructions (a makefile or even worse) to obtain a binary version in a single file, and a header file, as described before.
This is because the C++ standard does not the low level stuff that happens inside a compiler. There are lots of implementation details that were freely left for compiler vendors to do as they wanted, possibly trying to achieve better performance. This unfortunately means that it is difficult to distribute a simple library.
You can call another program easily - this will start an entirely separate copy of the program. See the system() or exec() family of calls.
This is common in unix where there are lots of small programs which take an input stream of text, do something and write the output to the next program. Using these you could sort or search a set of data without having to write any more code.
On windows it's easy to start the default application for a file automatically, so you could write a pdf file and start the default app for viewing a PDF. What is harder on Windows is to control a separate giu program - unless the program has deliberately written to allow remote control (eg with com/ole on windows) then you can't control anything the user does in that program.
I am trying to partially truncate (or shorten) an existing file, using fstream. I have tried writing an EOF character, but this seems to do nothing.
Any help would be appreciated...
I don't think you can. There are many functions for moving "up and down" the wrapper hierarchy for HANDLE<->int<->FILE *, at least on Windows, but there is no "proper" to extract the FILE * from an iostreams object (if indeed it is even implemented with one).
You may find this question to be of assistance.
Personally I would strongly recommend steering clear of iostreams, they're poorly designed, heavily C++, and nasty to look at. Take a look at Boost's iostreams, or wrap stdio.h if you need to use classes.
The relevant function for stdio is ftruncate().
The Boost.Interprocess library defines a portable truncate function. For some reason it is not documented, but you can find it this header file.
It'll depend on the OS. Most OSes support this, but in different ways. On Windows, there's a SetEndOfFile(). On Unix and similar systems, you lseek to where you want the file to end, and do an lwrite of zero bytes there. Other OSes undoubtedly use other methods.
I bit the bullet in the end and read the part of the file to be kept to an array then re-wrote it. It's not the best solution - but as the files will always be small I have decided to accept this method.