|
Hi!
I'm porting a library from unix/posix to Win32, and i have some troubles with the memory mapped file access.
I use mmap to read pages from the file, but use the normal write API to write the pages.
On unix, it looks like this:
buffer=mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, position);
On win32, it's a bit longer, as usual:
DWORD fsize=GetFileSize(fd, 0);
mmaph=CreateFileMapping(fd, 0, PAGE_READONLY, 0, fsize, 0);
buffer=MapViewOfFile(mmaph, PAGE_READWRITE, 0, (unsigned long)position, size);
My first problem is that CreateFileMapping is called whenever i read a page from the file. Is it an expensive operation? I just don't see a way to avoid this. If i cache the mmaph handle, and the file is resized because a page is appended, then this page is not covered by the file mapping...
The second problem: it just doesn't work. CreateFileMapping returns 0 and GetLastError is 5 (ACCESS_DENIED) when it's called for the very first time (fd is a valid file handle, and fsize is 4096).
The file handle was created with
CreateFile(filename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0);
Thanks for any help
Chris
|
|
|
|
|
I never used mapped files on Unix so I am unable to give you a comparison. If you wish to append data to a mapped file, try to specify a larger file size. In you code example you get the file size and use that, but it's perfectly safe to specify larger ( try to round it up to a 4k boundary for best performance ). Opening and closing the file is more expensive than mapping. I believe there is a flag to automatically grow the file for win2000+, but for the moment I just can't remember.
For your second problem, try using GENERIC_READ|GENERIC_WRITE, and try dropping the FILE_FLAG_OVERLAPPED.
|
|
|
|
|
According to the MSDN documentation, you can specify a larger size for the view, but then the file is resized:
"If an application specifies a size for the file mapping object that is larger than the size of the actual named file on disk, the file on disk is increased to match the specified size of the file mapping object."
And that's not what i want, because my library is a database library, and it depends on the user if he wants to insert a lot of data - or insert nothing. in the first case, my view has to "grow", in the second case, the file should stay small...
But anyway, this is the smaller problem of the two. I tried using GENERIC_READ|GENERIC_WRITE and dropped the FILE_FLAG_OVERLAPPED, but i still get error 5 (ACCESS_DENIED) when calling CreateFileMapping...
|
|
|
|
|
Hi all
i have created a simple console application calculating quotations for carpet cost. At the moment it ask user for name, lenght of room and do all calculation and produce output giving detail of the cost.
But now i want that details of previous customer quotation records which are held in a file named “quotes.txt” (a file of records qordered by unique uotation reference numbers). At the start of the program, the file will be loaded into an array of structures called “Quotes” in order that new quote records can be appended and the records can be viewed on screen. The updated file will be saved when the program exits.
So i am stucked here, please help me out. Please see the code below and guide me the right way to add the above functionality...
Thanks a lot
void main()
{
float Length=0, Width=0, Area=0, Cost=0, DeliveryCharge=0;
int UnitPrice=0, GuaranteePeriod=0, DelDistance=0, QuoteNum=INITIAL_QUOTE_REF_NUM;
char AnotherQuote, DelRequired;
char Name[NAME_LEN];
bool ValidPrice;
fstream InputFile;
do
{
//clrscr();
cout << "\nPlease enter surname and initials: ";
cin >> ws;
cin.getline(Name,NAME_LEN);
cout << "Please enter length of room: ";
cin >> Length;
cout << "Please enter width of room: ";
cin >> Width;
do
{
DeliveryCharge=0;
ValidPrice = true;
cout << "Please enter the price per square metre from the following price range:\n\n";
cout << POUND_SIGN << QUALITY_1 << ", " << POUND_SIGN << QUALITY_2 << ", " << POUND_SIGN
<< QUALITY_3 << ", " << POUND_SIGN << QUALITY_4 << ", " << POUND_SIGN << QUALITY_5 << "\n\n" << POUND_SIGN;
cin >> UnitPrice;
cout << "\n\n";
//Assign correct guarantee period for unit price entered.
switch(UnitPrice)
{
case QUALITY_1 : GuaranteePeriod=GUARANTEE_Q1; break;
case QUALITY_2 : GuaranteePeriod=GUARANTEE_Q2; break;
case QUALITY_3 : GuaranteePeriod=GUARANTEE_Q3; break;
case QUALITY_4 : GuaranteePeriod=GUARANTEE_Q4; break;
case QUALITY_5 : GuaranteePeriod=GUARANTEE_Q5; break;
default : cout << "\n\nInvalid price.\n\n";
ValidPrice = false;
}
}while (!ValidPrice);
Area = Length * Width;
Cost = Area * UnitPrice;
cout << "Do you require delivery? (Y/N) ";
cin >> DelRequired;
//Force correct input to delivery question.
while(toupper(DelRequired)!='Y' && toupper(DelRequired)!='N')
{
cout << "Invalid character - enter Y or N:";
cin >> DelRequired;
}
if(toupper(DelRequired)=='Y')
{
cout << "\n\nPlease enter delivery distance in miles: ";
cin >> DelDistance;
if(DelDistance >=0 && DelDistance <=ZONE1)
{
DeliveryCharge = Cost * ZONE1_CHARGE;
}
else
{
if(DelDistance <=ZONE2)
{
DeliveryCharge = Cost * ZONE2_CHARGE;
}
else
{
if(DelDistance <=ZONE3)
{
DeliveryCharge = Cost * ZONE3_CHARGE;
}
else
{
DeliveryCharge = Cost * ZONE4_CHARGE;
}
} //end else > ZONE2
} //end else > ZONE1
} //end delivery required
cout << endl << endl << endl
<< setfill('_') << setw(TABLE_WIDTH) << "" << "\n\n"
<< setfill(' ')
<< setw(7) << " Ref | " << setw(NAME_COL_WIDTH) << " Name | " << setw(COST_COL_WIDTH) << "Carpet | " << setw(DELIVERY_COL_WIDTH)
<< "Delivery | " << setw(TOTAL_COL_WIDTH) << " Total | " << setw(GUARANTEE_COL_WIDTH+7) << "Guarantee |" << endl
<< setfill('_') << setw(TABLE_WIDTH) << "" << "\n\n" << setfill(' ');
cout << fixed << showpoint << setprecision(2);
cout << setfill(' ')
<< setw(7) << QuoteNum << " | "
<< setw(NAME_COL_WIDTH) << Name << " | "
<< setw(1) << POUND_SIGN << setw(COST_COL_WIDTH-4) << Cost << " | "
<< setw(1) << POUND_SIGN << setw(DELIVERY_COL_WIDTH-4) << DeliveryCharge << " | "
<< setw(1) << POUND_SIGN << setw(TOTAL_COL_WIDTH-1) << Cost + DeliveryCharge << " | "
<< setw(7) << "Years: " << setw(GUARANTEE_COL_WIDTH) << GuaranteePeriod << " |"
<< endl;
cout << "\n\nEnter another quote?";
cin >> AnotherQuote;
} while(AnotherQuote=='Y'||AnotherQuote=='y');
///THIS IS WHAT I TRIED, BUT ITS NOT READING THE FILE.........////
/*char FileString[512];
InputFile.open("\\Quotes\\CarpetQuotes.txt", ios::in);
if(InputFile.is_open())
{
InputFile.getline(FileString, sizeof(FileString));
}
*/
cout << "\n" << endl;
system("pause");
}
-- modified at 8:12 Sunday 18th February, 2007
|
|
|
|
|
Before we can help you, we need to know exactly how the text file is structured. ie, is it 1 customer per line, are items seperated by anything? Perhaps if you show us an example of the first few customers.
Also, you say you want to load it into a struct, how is the struct defined? What iformation does it hold and in what format?
Also, it's necessary to post so much code in the forum. Always try to keep your snippets as small as possible and only show us the section you feel has a problem, unless asked otherwise.
|
|
|
|
|
The format of the text is as follows:-
Quote Number
Customer Surname & Initials
Cost of carpet
Delivery cost
Guarantee
So text file is like below:-
1000
Snape LC
3003.00
900.90
2
1001
Bond J
6936.00
0.00
4
Well i have not defined the struct as yet. I am lil confused about this part. If you could refer me any example or something similar then it would be gr8..
And yeh ill keep in mind about snippets...
Thanks for replying
|
|
|
|
|
OK, now I see.
For this to work correctly, you must be certain that each customer is layed out the same. IE, if you have yet to create a cost, within the text file you should place 0 and not an empty line.
For the struct, I would do something like
struct CUSTOMER<br />
{<br />
DWORD QuoteNumber;<br />
CHAR Surname[56];<br />
CHAR Initials[2];<br />
DWORD CarpetCost;
DWORD DeliveryCost;<br />
SHORT Guarantee;
}
Now since the file is layed out with 5 lines per customer, I would create a function to read a single customer then call this in a loop until there are non remaining.
bool ReadCustomerDetails( FILE* hFile, CUSTOMER* pCustomer )
Open the file with fopen(), read each line with gets() then depending on the which line you read convert it to the datatype in the struct.
Have a go at coding that, need any help just say the word.
|
|
|
|
|
WalderMort wrote: Now since the file is layed out with 5 lines per customer, I would create a function to read a single customer then call this in a loop until there are non remaining.
bool ReadCustomerDetails( FILE* hFile, CUSTOMER* pCustomer )
Open the file with fopen(), read each line with gets() then depending on the which line you read convert it to the datatype in the struct.
Your struct is good, but I would opt for reading/writing it as binary instead so that one fread() could be used per record, rather than multiple fgets() calls.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
If I were to code something like this myself, I probably would. But given that the OP comes across as a bit of a newbie I don't want to confuse him too much
|
|
|
|
|
Thanks, its making some sence now...
I was confused with this part as in specs it was written that file would be loaded to array of structurs in order that new records can be appended and the records can be viewed on screen. So i guess its just to create a struct with all the fields which are included in text..and then text is just called and saved...
I have started coding for it. Would ask you if i face any further problems..
Thanks a lot..
|
|
|
|
|
Why on earth use a Text File for this! If it HAS to be a Text File, I would add a Sync Key at the start of each record. (This is Line of Text such as:"$$$***&&&?//??**<<>>"). You scan this line at the start of each record, and compare it with your Hardcoded String. If it does not compare, you're out of sync. This means that you are alerted to something being wrong, and you have atleast some hope of recovery.
The way I would approach this would be to store the structures directly in the file as binary. Keep in mind that what starts now as small data, will in time grow into a huge record. Searching in a Huge textfile ends up time consuming. Weeding out redundant records can be problematic.
LateNightsInNewry
|
|
|
|
|
how can i display the thumbnail preview of the images on the view?
Regards,
Srinivas
|
|
|
|
|
You dont need to ask a same question
|
|
|
|
|
Do you know what a thumbnal IS? If so, then you should also know that displaying a mini-version
of a bitmap image is done the same way as displaying the big one, right?
Great job, team. Head back to base for debriefing and cocktails.
|
|
|
|
|
I am using Visual Studio 6.0. VS resource editor does not support unicode. So when I write some polish characters in string table or dialog controller "??" values are shown. How should I make a resource file/ resource dll for Polish language?
Thanks in advance.
|
|
|
|
|
See my answers in this thread[^].
Ovidiu Cucu
Microsoft MVP - Visual C++
|
|
|
|
|
how can i display the thumbnail preview of the images on the view?
Regards,
Srinivas
|
|
|
|
|
Where do you want to show this preview main dialog or other dialog?
|
|
|
|
|
i taken one SDI Applacation ..
and i want to show the preview of images on the view(like bmp , png ..ect) ...
view means (CView,or TreeView)
Regards,
Srinivas
|
|
|
|
|
You can use of CImage or GDI+ for show these formats.
and if you want to thumbnail of all images I suggest use of CListCtrl
|
|
|
|
|
how can i add the Media player control on List view?
Regards,
Srinivas
|
|
|
|
|
Can you clear explain,do you want to show movie files?
|
|
|
|
|
Hey Guys,
This might sound like a silly question but does Visual C++ 6 run on Windows Vista? May faithful Win2K laptop is starting to die and I need a replacement and it looks as though I might be stuck with Windows Vista.
Best regards
Danny
|
|
|
|
|
Yes, I know it does. But, why would you stick with such a bad C++ compiler ?
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
I agree that MSVC6 sucks but not everyone can upgrade on a whim. We still use MSVC6 where I work and will only upgrade when the "powers that be" decide. I'm not holding my breath.
Steve
|
|
|
|
|