|
Memory mapping allows you to treat a file, or portion of a file, as an array of bytes, just like any other array in C/C++.
I suggest you read about it here[^], since it can be quite a complex topic.
|
|
|
|
|
can i used it for reading the 64gb of data should i have to create the MMF and the i have to read ?......
here i am trying to take the c drives which of 64gb displaying in windows client area .for this how to create MMF and to Read. i know the function of MMF but not able to implement if in proper way give me example to create and read the data for particular on drives ...........
thanking you
sarfaraz
|
|
|
|
|
This is almost impossible to tell without knowing your data.
Do you have one 64GB file, or many smaller with a total of 64GB? Are they text or binary files?
If you want to display one big file in a window, you can map a portion of the file around the part you want to display, and read that information. But without knowing the data structure of your file(s), it's hard to tell how to sync data with display. E.g. if you have a text file, you might want to manage some line or character count to calculate which portion of the file to map. If it's structured binary, you need something similar.
Please give some info on what you have, and how you want it displayed.
|
|
|
|
|
thanks
its is \\C: drive i am want to display in hexadecimal
|
|
|
|
|
as you usually read full sectors when accessing the hdd, you should use normal file i/o for it.
allocate a buffer that is big enough to keep the maximum amount of data the hex editor can display and read it from disk just the way you to with a normal file.
memory mapping 64gb can only work with 64-bit os, as it requires a very big virtual address space. but i haven't tried to map that much data so far.
Don't try it, just do it!
|
|
|
|
|
Here is a sample of how to map a small portion of a large file:
const TCHAR* path = _T("C:\\file.dat");
DWORD maxBytesToMap = 64*1024;
HANDLE hFile = ::CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
DWORD fileSizeHigh;
DWORD fileSizeLow = ::GetFileSize(hFile, &fileSizeHigh);
HANDLE hShMem = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
unsigned char* pBytes = (unsigned char*)::MapViewOfFile(hShMem, FILE_MAP_READ,
fileOffsetHigh, fileOffsetLow, maxBytesToMap);
for (size_t i = 0; i < byteCount; ++i)
x = pBytes[i];
Error checking and clean-up omitted.
|
|
|
|
|
thanks
1)i tried but not able to understand what actually memory mapped file will do ....
2)i also studied in MSDN about this but i not understood the virtual address space ...
3)how it will access the data ......
please clear the above points.........
now see how i had written the code for this....
HANDLE hfile,hmapfile;
hfile = CreateFile(_T("C:\\saad.txt"),GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hfile == INVALID_HANDLE_VALUE)
{
MessageBox(_T("Fail to open the drive"),_T(" "),MB_OK | MB_ICONERROR);
return -1;
}
DWORD filesize = GetFileSize(hfile,NULL);
hmapfile = CreateFileMapping(hfile,NULL,PAGE_READWRITE |PAGE_WRITECOPY |SEC_COMMIT |SEC_RESERVE,filesize,filesize,NULL);
if(hfile == INVALID_HANDLE_VALUE)
{
MessageBox(_T("Fail to open the drive"),_T(" "),MB_OK | MB_ICONERROR);
return -1;
}
DWORD pbuf = (DWORD) MapViewOfFile(hmapfile,FILE_MAP_COPY |FILE_MAP_ALL_ACCESS,0,filesize,filesize);
one more thing i want ask should i have read the file with Readfile ???
|
|
|
|
|
sarfaraznawaz wrote: 1)i tried but not able to understand what actually memory mapped file will do ....
A memory mapped file is faster than than reading a file the conventional way. On the other hand, if you are reading/writing text, you will not benefit from having end line characters translated correctly for you, and have to do that manually.
sarfaraznawaz wrote: 2)i also studied in MSDN about this but i not understood the virtual address space ...
The virtual address space is nothing you have to worry about yet. It is the memory your process is able to read. The operating system will help you take care of business. However, a 32 bit application can never address more space than can be stored in a 32 bit unsigned type variable. This is why mapping 64Gb data all at once will be a problem.
sarfaraznawaz wrote: 3)how it will access the data ......
You access the data just as any other C/C++ array, by offsetting the returned pointer from MapViewOfFile().
sarfaraznawaz wrote: one more thing i want ask should i have read the file with Readfile ???
It looks like using ReadFile() would be a dead end if you want to display the entire file. My guess is that you will suffer from real performance problems.
|
|
|
|
|
thanks
i mapped the file but not able to display whole file in the window
|
|
|
|
|
You should only display a small portion of the file at any one time. You don't need to show more than fits (+ maybe a little extra for performance)
The user won't notice since he/she cannot seethe whole file anyway. Manage scrollbars manually.
|
|
|
|
|
thanks again ...
but i not understand clearly the parameter DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow in CreateFileMapping(......)
even in PVOID MapViewOfFile(DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,)not understood ..
please clear it ....
|
|
|
|
|
Your DWORD is a 32 bit unsigned integer. That means it can store values up to 4 * 1024 * 1024 * 1024. You cannot point to anything higher than that in your file by just using one DWORD. This equals 4GByte. To be able to read data from a file larger than 4Gbyte, you will have to make use of the dwFileOffsetHigh, which simply speaking is the index of the 4Gbyte block in the file you want to read. For the first 4Gbyte, dwFileOffsetHigh should be zero, for the next 4Gbyte data, ranging from 4Gbyte to 8Gbyte, it should be 1, and so on. You have to do some simple math there to calculate the correct offset for your desired view.
|
|
|
|
|
thanks ....
i written the code which is to read the c:drive its showing the bad pointer here my code
hfile = CreateFile(_T("\\\\.\\C:"),GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD filesizeLow = GetFileSize(hfile,&fileSizeHigh);
HANDLE hmapfile = CreateFileMapping(hfile,NULL,PAGE_READONLY ,0,0,NULL);
if(hfile == INVALID_HANDLE_VALUE)
{
MessageBox(_T("Fail to open the drive"),_T(" "),MB_OK | MB_ICONERROR);
return -1;
}
CloseHandle(hfile);
pbuf = (BYTE*) MapViewOfFile(hmapfile,FILE_MAP_READ ,0,0,filesizeLow);
but its ok with the simple text file ......
one more thing i want to ask that is there any way to hide the folder or file........
|
|
|
|
|
I can spot two problems with your code.
1. You cannot read a drive. You have to read a file. What exactly is it you want to do? If you want to read raw data from the hard drive sector by sector, you'll need a different API.
2. You cannot close the handle before accessing the file mapping. Read what you have to, and close the file once you're done.
sarfaraznawaz wrote: one more thing i want to ask that is there any way to hide the folder or file.....
I saw you started a new thread for this, which is good. Keep that discussion there, and you will more likely attract others who might know.
|
|
|
|
|
thanks ...........
ya i want to read raw data from the hard drive sector by sector which is are the API are there
|
|
|
|
|
I found the following article on MSDN[^]. It's for reading sectors off a CD_ROM drive. Maybe it's possible for hard drives as well.
If not, I suggest you start a new thread with this more specific requirement. (Reading sector by sector.)
|
|
|
|
|
How to use Microsoft Scripting Runtime in WIN32 C++
want to use this function GetDrive("C:\").IsReady
Some Day I Will Prove MySelf :: GOLD
|
|
|
|
|
|
using vs 2008...
I'm trying to implement my own version of the standard library function:
#include <algorithm>;
copy( b, e, d ) ;
but, the line that calls 'my function' gives this error:
error C2668: 'copy' : ambiguous call to overloaded function
I'm guessing copy() is overloaded as it exists already in the standard lib...but I haven't included algorithm..so how would it know???
..also as a side note, if I change the name of 'my function' from copy to..it seems anything else
then I get the error:
error C2676: binary '++' : 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator
from line:
*dest++ = *begin++;
--------------------------------
#include <string>
using std::string ;
template <class In, class Out>
Out copy( In begin, In end, Out dest )
{
while ( begin != end ) {
*dest++ = *begin++ ;
}
return dest ;
}
int main() {
string s = "the fox jumped over the moon" ;
string d ;
copy( s.begin(), s.end(), d ) ;
return 0 ;
}
|
|
|
|
|
You have two different problems.
The "++ error" comes from the fact that you send a std::string as the third parameter to copy. As the compiler says, std::string has no overloaded ++operator. You should instead use an output_iterator.
The name clash problem might come from another header including algorithm. Make use of the namespace qualifiers, and avoid using namespace std;
A good idea is to put your own copy function inside a namespace you choose.
|
|
|
|
|
Niklas Lindquist wrote: The "++ error" comes from the fact that you send a std::string as the third parameter to copy. As the compiler says, std::string has no overloaded ++operator. You should instead use an output_iterator.
doh ..how did i miss that
Niklas Lindquist wrote: The name clash problem might come from another header including algorithm. Make use of the namespace qualifiers, and avoid
using namespace std;<br />
<br />
A good idea is to put your own copy function inside a namespace you choose.<br />
ahh ..something new learned ..that worked a treat thanks
#include <string>
#include <iterator>
namespace custom{
template <class In, class Out>
Out copy( In begin, In end, Out dest )
{
while ( begin != end ) {
*dest++ = *begin++ ;
}
return dest ;
}
}
int main() {
std::string s = "the fox jumped over the moon" ;
std::string d ;
custom::copy( s.begin(), s.end(), std::back_inserter( d ) );
return 0 ;
}
|
|
|
|
|
tukbriz wrote: I'm guessing copy() is overloaded as it exists already in the standard lib.
Correct. Compiler shall show you where it find the ambiguity. Have a look into it.
tukbriz wrote: *dest++ = *begin++ ;
This statement makes the error, and the reason is clear - std::string class doesn't have ++ operator overloaded.
What are you exactly trying to do?
|
|
|
|
|
I have a problem about trying to change the color of selected/hilight row of CMFCListCtrl/CListCtrl when they are not in focus.
the control are already set with "full row select" styles
On windows xp or classic theme there is no problem.
but when using aero theme (both vista and 7) the color of selected row when it doesn't have a focus is a "very" light grey (opposed to darkgrey on old version of windows/classic theme)
that absolutely cannot be seen on my Laptop screen/LCD/50 inch HDTV.
I tried to implement the color changing by using custom draw but look like it impossible to change the selected cell/row color (only unselected cell/row color can be change). or it already
changed but the system draw the default selected background after custom draw,I dont know.
Please help me if anyone know the solution without resorting to full owner drawn implement (I dont have that much experience to recreate all the drawing code).
this is my current attemp which didn't work
void CMyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
switch(lpLVCustomDraw->nmcd.dwDrawStage)
{
case CDDS_ITEMPREPAINT:
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
if(this->GetItemState(lpLVCustomDraw->nmcd.dwItemSpec,LVIS_SELECTED) & LVIS_SELECTED){
lpLVCustomDraw->clrTextBk = RGB(0,0,0);
}
break;
default: break;
}
*pResult = 0;
*pResult |= CDRF_NOTIFYPOSTPAINT;
*pResult |= CDRF_NOTIFYITEMDRAW;
*pResult |= CDRF_NOTIFYSUBITEMDRAW;
}
|
|
|
|
|
Try doing this :-
if(this->GetItemState(lpLVCustomDraw->nmcd.dwItemSpec,LVIS_SELECTED) & LVIS_SELECTED){
lpLVCustomDraw->clrTextBk = RGB(0,0,0);
lpLVCustomDraw->nmcd.uItemState &= ~CDIS_SELECTED;
}
break;
I discovered this the other day after puzzling over a similar issue for months.
|
|
|
|
|
Holy ****, It work !!!
Thank a lot man,you just save my life.
Can you tell me why It has to remove (?) CDIS_SELECTED from the uItemState to make it work ?
|
|
|
|
|