[iostreams] detecting io errors

Hello, I use boost:iostreams for reading and writing a binary data format. There is currently no use of filters, but the reason for using boost was to try using compression by adding a filter. I have run into some problems/questions regarding the boost:iostreams::stream class though, and was hoping that someone here might give me a hint. The files I save is project files, and the users use a versioning system to lock the files while editing. Occasionally they forget to lock and would get an error when trying to save, since the files in write protected unless locked. My first (and worst) problem was that i did not get any error at all when the write failed, I found out that this was my own fault since I used: bio::stream<bio::file_sink> outs(tstFileName, std::ios_base::out); // ... write etc... if (outs.is_open()) // error ... instead of if (outs->is_open()) // ^^ '->', not '.' must be used here // error ... but it seem like an easy pitfall for newbies like me. A different method name or at least a warning in the documentation maybe? The second problem is that I cannot find any way to get information on the nature of the write error. E g is it an access permission problem or a hardware error? The third problem is that seem to be no way to detect an error when closing the file. I have attached a short c-file to illustrate what I would want to know. I pause and remove the USB-stick with the open file before closing. c-runtime streams will give me error on close, but I cant get the same information out of boost::iostreams. Any help, directions or opinions would be appreciated. Best regards, Johan Grafström /* -*- mode: C++; coding: utf-8-dos; -*- */ /* ========================================================================== * boost_test2.cpp * * Problems: * * * Boost only reports false for outs->is_open() after error but gives no * details (write failure, invalid handle, access violation) * * * An error on file close cannot be detected * * * The worst problem was my own: * using outs.is_open() (always returns true) * instead of outs->is_open() returns false after error * * ========================================================================== */ #include <stdio.h> #include <conio.h> #include <boost/iostreams/device/file.hpp> #include <boost/iostreams/stream.hpp> void boostWriteTestFile(); void streamsWriteTestFile(); void userInteract(); namespace bio = boost::iostreams; char tstFileName[] = "write_test.txt"; int main(int argc, char *argv[]) { // DebugBreak(); if (argc == 2 && strcmp(argv[1],"streams") == 0) { printf("Write using c-runtime stream i/o\n"); streamsWriteTestFile(); } else { printf("Write using boost:iostreams\n"); boostWriteTestFile(); } return 0; } void boostWriteTestFile() { char streamText[] = "Written by boost iostreams api\n"; int msgSize = strlen(streamText); // write using boost bio::stream<bio::file_sink> outs(tstFileName, std::ios_base::out | std::ios_base::binary); int bytesWritten = outs->write(streamText, msgSize); if (bytesWritten != msgSize) printf("Error boost writing\n"); if (!outs->is_open()) printf("Error boost file closed\n"); userInteract(); // Problem: how to get error status from outs.close() ?? // returns void // in boost/iostreams/device/file.hpp:175 // template<typename Ch> // void basic_file<Ch>::close() { pimpl_->file_.close(); } // returns void thus ignoring the return value from // basic_filebuf.close() in c++ runtime <fstream> outs.close(); } void streamsWriteTestFile() { char streamText[] = "Written by c-runtume streams api\n"; int msgSize = strlen(streamText); // write using c-runtime streams FILE *fh = fopen(tstFileName, "w"); if (fh == NULL) { perror("on fopen()"); return; } size_t countWritten = fwrite( streamText, // const void *buffer, 1, // size_t size, msgSize, // size_t count, fh // FILE *stream ); if (countWritten != msgSize) { perror("On fwrite()"); return; } userInteract(); int status = fclose(fh); if (status == 0) { // ok } else { // status == EOF perror("on fclose()"); return; } } void userInteract() { printf("Please remove the file %s, in some apropriate manner e g \n" "remove the floppy or usb-drive, delete with Unlocker or equivalent.\n" "Then press any key to continue.\n", tstFileName); _getch(); }
participants (1)
-
Johan Grafstrom