Years ago I created a C++ function using FILE to create bitmap files. Recently (not sure when or why) this code is now failing when opening the file. The problem is with the open call ...
file_ptr = fopen("ScreenShots/Screenshot1.bmp", "wb");
Currently this results in an error 13, permission denied error. Change the filename extension to something else and the fopen works fine. For example,
file_ptr = fopen("ScreenShots/Screenshot1.bm2", "wb");
The file saves correctly and when changing the extension back to BMP I can display the file correctly in Paintshop.
Did a quick check using ofstream and same problem.
Any ideas why I get a permission denied error when trying to open BMP files to write data? For information I am using Visual Studio Community 2017 on Windows 10.
To give the complete section of code ...
BITMAPFILEHEADER bitmap_header;
BITMAPINFOHEADER bitmap_info;
FILE *file_ptr;
unsigned int count;
unsigned char tempRGB;
char filename[256];
bool finished;
// CREATE A UNIQUE FILENAME
count = 1;
finished = false;
do
{
// CREATE NAME
sprintf(filename, "ScreenShots/Screenshot%d.bmp", count);
// CHECK IF FILE EXISTS
errno = 0;
file_ptr = fopen(filename, "rb");
if (file_ptr)
{
// FILE EXISTS
fclose(file_ptr);
count = count + 1;
}
else
{
// UNIQUE FILENAME
file_ptr = fopen(filename, "wb");
if (file_ptr == NULL)
{
// UNABLE TO OPEN FOR WRITING - GIVE UP
// (USING OWN LOGGING CLASS)
jalog.log("\nERROR on Screenshot >");
jalog.log(filename);
jalog.log("< >");
jalog.log((short)errno);
return;
}
finished = true;
}
}
while (finished == false);
I've managed to find the issue ... Avast antivirus. I noticed that trying to do an open action for a BMP file took a few seconds while opening any other file type (successfully or unsuccessfully) was instantaneous. As something similar happens when running new programs I tried disabling all the Avast shields and I could successfully create a BMP file using the existing code.
For my own personal use I can whitelist my own programs, but annoying if I get to distributing the program to other people.
Thanks for the help ... and sorry for raising a C++ issue that in the end had nothing to do with C++!
Related
I writing ESP32 program and using SPIFFS to save some data because I do not want to loose it after I power down the device.
I have 2 functions:
char* readFile(fs::FS &fs, const char *path)
{
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file || file.isDirectory())
{
Serial.println("Failed to open file for reading");
return "FAIL";
}
Serial.print("Read from file: ");
while (file.available())
{
Serial.write(file.read());
delayMicroseconds(100);
//TODO
//append all characters and return it as a list of char arrays at the end of reading
}
file.close();
}
void writeFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
Serial.println("Failed to open file for writing");
return;
}
if (file.print(message))
{
Serial.println("File written");
}
else
{
Serial.println("Write failed");
}
file.close();
}
First of all, I run my program and call writeFile() and then followed by readFile():
int n = 0;
Wifi_setup();
Spiffs_setup();
n = scan_wifi_networks();
Serial.print("list_strings outside scan function = ");
for (int i = 0 ; i<=n ; i++){
Serial.println(found_networks[i]);
}
//compare list_strings with preset wifi networks. If match, everything is fine, if not, problem!
writeFile(SPIFFS, "/wifi.txt", "Telia-33F8A3-Greitas");
char* known_networks = readFile(SPIFFS, "/wifi.txt");
//send USD to the server, go back to sleep
//initialize_deep_sleep();
}
And that part works fine. From the serial monitor, I can see that it have sucesfully written my text to wifi.txt.
After I run write/read functions
Next, I comment out write function and only leave read function.I run the code again and it is not able to read back my text:
Only readFile
Can someone help me understand why is that happening? I thought that if I write to spiffs once, I will be able to access it afterwards but that is not the case. I have previously used EEPROM and that seemed to work. I can write to EEPROM address and simply access the same address later and the value will still be there after the power off. Any help is appreciated. Thanks in advance.
UPDATE1
I have managed to read back data from my SPIFFS after I wrote to it. I had missed one crucial step:
https://randomnerdtutorials.com/install-esp32-filesystem-uploader-arduino-ide/
However, now, I am encountering another issue:
In my project folder, I have created a folder "data" which is supposed to be accessed by SPIFFS. In there, I create 2 files :
wifi.txt
update.bin
update.bin for now is not relevant. Lets talk about wifi.txt
After I have written to Spiffs, I now comment out the writeFile function and only leave out readFile. The result from my serial monitor:
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Listing directory: /
FILE: /update.bin SIZE: 0
FILE: /wifi.txt SIZE: 20
Reading file: /wifi.txt
Read from file: Telia-33F8A3-Greitas
As you can see from the serial monitor above, my program recognises the text that I have written to my spifs /wifi.txt file. Howeverm when I go to my actual project directory and open data/wifi.txt it is emtpy:
How can this happen? My program recongises that theres data inside but it wont show up in the file.
UPDATE2
I have done some further testing of SPIFFS.
In my data folder, I have created another txt file test.txt. In there, I have manually put some text "this is text message".
In my program, I have called function:
char* returned_data = readFile(SPIFFS, "/test.txt");
And the serial monitor sucesfully printed the message that I have put. So that proves that the SPIFFS is able to read back from the files without any issues.
Then, I have modified my program:
writeFile(SPIFFS, "/test.txt", "hello123");
char* returned_data = readFile(SPIFFS, "/test.txt");
The code above should overwrite whatever I have written to my txt file with "hello123" and then my program should read the "hello123" back from Spiffs. The serial monitor response:
Listing directory: /
FILE: /update.bin SIZE: 0
FILE: /wifi.txt SIZE: 2
FILE: /test.txt SIZE: 8
Writing file: /test.txt
File written
Reading file: /wifi.txt
Read from file:
Reading file: /test.txt
Read from file: hello123
As you can see, it is able to sucesfully read back "hello123".
HOWEVER, when I go to my project folder, open the data/test.txt, I can still see my initial text not replaced with "hello123".
I do not understand how is this happening..
I am trying to open a file for this program. I have tried pathing it directly using examples like C:\User... but for some reason it still says it can't find the file. I have looked on the internet as well as youtube to open files using C++ and its pretty straight forward. However I still can't get this .txt file to be read. Maybe it has to do with Visual Studio?
FILE* in_fp, * fopen();
int main() {
if ((in_fp = fopen("TextFile.txt", "r")) == NULL)
printf("ERROR - cannot open front.in \n");
else
{
getChar();
do {
lex();
} while (nextToken != EOF);
}
}
I have following function isEthernetCableConnected() which I am calling in a thread in continuous loop. After a long time I started to get log "Could not open /sys/class/net/eth0/carrier". How can it be possible? If it is possible then please give me some idea how to open the file every time.
ETH_FILE_CARRIER /sys/class/net/eth0/carrier
int isEthernetCableConnected(){
FILE *fp = fopen(ETH_FILE_CARRIER, "r");
int result;
if(fp == NULL) {
CLog::getInstance()->error("utility",__LINE__,__FILE__,"networked::isEthernetConnected, Could not open %s", ETH_FILE_CARRIER);
return 0;
}
fscanf(fp,"%d",&result);
fclose(fp);
return result;
}
Please refer the below link, it might help you
http://wikistack.com/how-to-check-if-ethernet-cable-is-connected-linux
In this link, they are trying to open the file in different way. May be you can try that.
I'm trying to create an xml file using pugixml. The code is;
//Open the save as diolog
TCHAR szFilters[]= _T("Files (*.abc)|*.abc|All Files (*.*)|*.*||");
// Create an SaveAs dialog; the default file name extension is ".abc".
CFileDialog fileDlg(FALSE, _T("abc"), NULL,
OFN_OVERWRITEPROMPT |OFN_CREATEPROMPT| OFN_PATHMUSTEXIST, szFilters);
// Display the file dialog.
CString pathName;
CString fileName;
if(fileDlg.DoModal() == IDOK)
{
pathName = fileDlg.GetPathName();
fileName = fileDlg.GetFileName();
::CreateFile(pathName,GENERIC_WRITE,0,NULL,CREATE_NEW, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
} //File is created in explorer
else
return;
//[code_modify_add
// add node with some name
pugi::xml_document xmlDoc;
pugi::xml_parse_result result = xmlDoc.load_file(fileName);
The problem is result always gives out a 'file_not_found' status, but I can see that the file is created in windows explorer. When I try to select the same file during the execution of the program it still returns 'file_not_found'.
However if I close the program and run again and then select the file, result returns true.
I noticed that while the program is executing I cannot open the newly created file, but when the program is closed I can open it.
What could be the matter with it?
Thanks.
You are creating a file and leaving it open write only with a share mode of zero (meaning it can not be shared) and throwing away its handle and then trying to reopen the file for reading with the xml parser.
You probably want to CloseHandle() on the return value for ::CreateFile()
HANDLE hFile = ::CreateFile(pathName,GENERIC_WRITE,0,NULL,CREATE_NEW, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (hFile == INVALID_HANDLE_VALUE) {
// Call GetLastError() to figure out why the file creation failed.
}
else
{
CloseHandle(hFile);
}
I have a project in C++ Builder6. There's an OpenDialog where I upload images to the project. I'd like my project to be safe and because it only accepts .jpg or .bmp images I decided to make a restriction. As far as I'm concerned I can recognize a .jpg file by setting my stream reader to the 4th position. If I find "JFIF" here, It'll be .jpeg file. And so on.
Here's my code
if(OpenDialog1->Execute())
{
TFileStream *stream = new TFileStream(OpenDialog1->FileName, fmOpenRead);
if(stream != NULL)
{
if(stream->Size < 10)
{
delete stream;
return;
}
char str[10];
stream->Read(str, 10);
if(AnsiString(str + 6).SetLength(4)=="JFIF")
{
ShowMessage("It's jpeg");
}
else if ( AnsiString(str).SetLength(2)=="BM") {
ShowMessage("It's bmp");
}
else
{
ShowMessage("It can not be downloaded");
return;
}
}
delete stream;
}
But unfortunately that code raises an exception about JPEG error #41 when I put here a text file with renamed extension.
So my idea doesn't work. The whole question is:
Can I make my program return my error messages without using try-catch method?
By the way, I understand why the exception is being raised, because my jpeg file is empty. But I'd like to handle it using my own system, not the standart exception.