I'm having problems using native C++ to open a file located on a network drive on a Windows box. My code works fine if the file is local, but fails if the file is on a network share. I can read the file from Windows explorer perfectly fine.
ifstream ifs(cFilename);
if(ifs.is_open())
{
// Read file here. (This never works for a network path)
}
I've also tried this:
struct stat sb;
if (stat(cFilename, &sb) == 0)
{
// Read file here. (This never works for a network path)
}
My path is formatted correctly (e.g. "\\server\filename.ext"), but I still can't open it. Any ideas?
If the name is in the form \\server\filename, then it seems that might not be correct. I believe that typically it needs a share name as well:
\\server\share\filename
Also, make sure that in the code, you escape the backslashes (e.g., \\\\server\\share\\filename).
Related
I am reading a text file using C++. I am using the first line to indicate if the file has changed or not. For example, text file will look like :
0
9
After the text file has been changed I am flipping the first line. So, the new text file will look like:
1
5
C++ code will perform its functions after reading the new input from the text file. Currently, I am using infinite loop to detect changes in the text file. Is there any alternative implementation of detecting changes in the text file using C++? This is my solution so far:
do{
std::ifstream reader;
reader.open(READFILE);
if (!reader){
printf("Error opening the reader file!!");
exit(1);
}
reader >> status >> variable;
if(status != reader_file_status){
reader_file_status = status;
return true
}
} while(true);
filesystem change events are platform specific, so you'll need different solutions for different platforms.
osx: file system events api doc
freebsd/osx: kqueue doc
linux: inotify doc
windows: windows api doc
It seems some cross platform wrappers are around. A quick googling revealed:
https://github.com/emcrisostomo/fswatch (gpl3, osx/freebsd/linux/windows/solaris)
http://doc.qt.io/archives/qt-4.8/qfilesystemwatcher.html (lgpl, osx/freebsd/windows)
For completeness, I'm using C++ in Visual Studio 2012 under Windows 7.
I have some basic file reading code:
Defined in class:
std::ifstream iniFileHandle;
Method in question:
FileLoader::FILE_STATUS FileLoader::loadFile(const std::string& fullpathandfilename)
{
if (fullpathandfilename.empty())
{
iniFileStatus = FILE_NOT_SPECIFIED;
}
else // parameter has 'something'...
{
if (!doesFileExist(fullpathandfilename))
{
iniFileStatus = FILE_NOT_FOUND;
}
else // file found...
{
iniFileHandle.open(fullpathandfilename, std::ios::in);
if (!iniFileHandle.is_open()) // something went wrong
{
iniFileStatus = FILE_CANNOT_LOAD; // <== HOW TO TEST?
}
else // file opened!
{
iniFileStatus = FILE_OPEN;
}
}
}
return iniFileStatus;
}
All this works fine but I'm having difficulty getting coverage with Google Unit Tests.
What i'm missing is a way to simulate/create a scenario where is_open() fails.
I've tried:
read only files
the 'exe' being currently run
a file opened in another application
but they all open.
Is this error condition actually possible to occur? If so, how can I mimic the failure so I can test it?
As mentioned in the comments, trying to open a directory will cause is_open() to return false. The cases you tried all succeed because you open the file as read-only (std::ios::in, which is also the default for an ifstream).
I've tried:
a file opened in another application but they all open.
This happens because file is opened in share mode which allows reading for others. You need to open file in exclusive file access mode. To achieve it, if you use MSVS, you could pass the third parameter int _Prot to the ifstream, otherwise you could use CreateFile().
To emulate the problem you could open file exclusively used by Windows, e.g:
c:\pagefile.sys
create a any file, and set its permission as read only, and in your code try to open this file for writing
PROBLEM HISTORY:
Now I use Windows Media Player SDK 9 to play AVI files in my desktop application. It works well on Windows XP but when I try to run it on Windows 7 I caught an error - I can not remove AVI file immediately after playback. The problem is that there are opened file handles exist. On Windows XP I have 2 opened file handles during the playing file and they are closed after closing of playback window but on Windows 7 I have already 4 opened handles during the playing file and 2 of them remain after the closing of playback window. They are become free only after closing the application.
QUESTION:
How can I solve this problem? How to remove the file which has opened handles? May be exists something like "force deletion"?
The problem is that you're not the only one getting handles to your file. Other processes and services are also able to open the file. So deleting it isn't possible until they release their handles. You can rename the file while those handles are open. You can copy the file while those handles are open. Not sure if you can move the file to another container, however?
Other processes & services esp. including antivirus, indexing, etc.
Here's a function I wrote to accomplish "Immediate Delete" under Windows:
bool DeleteFileNow(const wchar_t * filename)
{
// don't do anything if the file doesn't exist!
if (!PathFileExistsW(filename))
return false;
// determine the path in which to store the temp filename
wchar_t path[MAX_PATH];
wcscpy_s(path, filename);
PathRemoveFileSpecW(path);
// generate a guaranteed to be unique temporary filename to house the pending delete
wchar_t tempname[MAX_PATH];
if (!GetTempFileNameW(path, L".xX", 0, tempname))
return false;
// move the real file to the dummy filename
if (!MoveFileExW(filename, tempname, MOVEFILE_REPLACE_EXISTING))
{
// clean up the temp file
DeleteFileW(tempname);
return false;
}
// queue the deletion (the OS will delete it when all handles (ours or other processes) close)
return DeleteFileW(tempname) != FALSE;
}
Technically you can delete a locked file by using MoveFileEx and passing in MOVEFILE_DELAY_UNTIL_REBOOT. When the lpNewFileName parameter is NULL, the Move turns into a delete and can delete a locked file. However, this is intended for installers and, among other issues, requires administrator privileges.
Have you checked which application is still using the avi file?
you can do this by using handle.exe. You can try deleting/moving the file after closing the process(es) that is/are using that file.
The alternative solution would be to use unlocker appliation (its free).
One of the above two method should fix your problem.
Have you already tried to ask WMP to release the handles instead? (IWMPCore::close seems to do that)
I am attempting to create an addon for Node.js that (among other things) writes content to a file inside my C++ class using ofstream.
std::ofstream license_file;
std::string fileContent(*NanAsciiString(args[0]));
license_file.open(PATH);
//file doesn't yet exist, so create it
if(!license_file) {
printf("ERROR: %s (%s)\n", strerror(errno), PATH);
}
license_file << fileContent;
license_file.close();
This works fine if PATH is set to the same directory as my Node.js code (e.g. ./license.txt).
However, ofstream fails to open/create the file in question if it is located anywhere else. For example, using ~/license.txt does not work (note: I'm running OSX).
The error reported is always No such file or directory -- even after I physically create ~/license.txt.
Any ideas why this works in one directory but not others? If it were a permissions issue I would expect a different error message.
For the record, I've seen about 20 other SO questions about "ofstream fails to create file" but passing additional flags into open() has no effect. I have a feeling this is somehow related to running inside Node/V8.
I think the issue is that you need to find out the user directory in a different way than using ~.
Well this time I'm trying to write a program in C which recover deleted files from a disk, it could be an external disk, I have an idea than i had used before on linux, it is to open the disk as a kind of file and scaning the Headers and file footers of everything within the disk, the point is I'm not sure if there's allow on windows to open a disk as an File, basiclly I have the logic how to develope this program, but I'm not sure how to implement it on windows, anybody can give me a hand with this?.
The code I used on linux to open a disk as a file was:
Edit: That was a sample of what I was using guys, it's just to give you an idea of what I was doing, the correct syntax I used was the next:
direccion = ui->linea->text().toLatin1().constData();
f = fopen(direccion,"rb");
I used QT creator on linux, and direccion variable was a TextField value which contained the file path of the disk through a button function that open a QFileDialog...
could I use it in windows as well?
Thank you before hand..
"The code I used on linux to open a disk as a file was:"
File *f = fopen("E:\", "rb");
I seriously doubt you ever got this code working on any linux system (or windows either).
You'll need to escape the backslash path delimiter, if it's presented in any string literal:
FILE* f = fopen("E:\\", "rb");
// ^
Also all that filesystem path style you are presenting to access a particular disk, is about accessing a windows file path/disk.
No linux file system has notion about drive characters, and the file path delimiter value used is '/', not '\\'.
To recover deleted files, you can't use fopen or fstream::open because the file was deleted. Check the return value from the function or test the stream state.
The way to recover deleted files is:
Get the Master File Table as raw data.
Search for the record containing a string similar to the deleted
filename.
Change the entry in the Master File Table to "undeleted".
Write the Master File Table back to the drive.
The above usually requires platform specific API, which is different on Linux and Windows platforms.