我现在要做一个工具,就是测试U盘文件的读写速度,创建一个文件往里面写数据,然后关闭该文件。然后再打开
这个文件从里面读数据,从而计算写的速度和读的速度。
      写没什么问题,速度都是正常数据,现在问题就是读的速度有问题,每次都是第一次读的时候,速度感觉是正常的,
而后面再去读的时候,速度就快的离谱,都可以达到100M/S。
      我感觉应该是第一次才是真正的从设备里面读数据,而后面的估计是因为之前读了一次,所以在缓存中有了拷贝,之后的数据就全部是从缓存中读的,所以才造成速度那么快,
      求高人指点,怎样在读数据之前可以把缓存清空,或者是怎么每次可以直接从设备读数据,十万火急,求救。
    注:读文件是用 CFile file 
                   file.Read(.. ..);

解决方案 »

  1.   

    你的测试范围也太小了,找个size比缓存大的文件,让它自己清空。
      

  2.   

    1.得到文件的Handle.
    2.得到FileObject对象
    ========================================
     RtlInitUnicodeString( &fileNameUnicodeString, filename );
            InitializeObjectAttributes( &objectAttributes, &fileNameUnicodeString, 
                OBJ_CASE_INSENSITIVE, NULL, NULL );
             
            ntStatus = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS, 
                &objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 
                FILE_OPEN, 
                FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, 
                NULL, 0 );
            if( !NT_SUCCESS( ntStatus ) )
            {            DbgPrint("svDrive: Could not open drive %c: %x\n", 'A'+Drive, ntStatus );
                return FALSE;
            }
           // ZwDeviceIoControlFile()
            DbgPrint("svDrive:  opened the root directory!!! handle: %x\n", ntFileHandle);           //
            // Got the file handle, so now look-up the file-object it refers to
            //
            //FILE_LIST_DIRECTORYReadDirectoryChangesW        ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA, 
                NULL, KernelMode, (PVOID*)(&fileObject), NULL );
    ================================================================3.删除缓冲区,参考《寒江独钓》中的代码void FileCacheClear(PFILE_OBJECT pFileObject)
    {
        PFSRTL_COMMON_FCB_HEADER pFcb;
        LARGE_INTEGER liInterval;
        BOOLEAN bNeedReleaseResource = FALSE;
        BOOLEAN bNeedReleasePagingIoResource = FALSE;
        KIRQL irql;    pFcb = (PFSRTL_COMMON_FCB_HEADER)pFileObject->FsContext;
        if(pFcb == NULL)
            return;    irql = KeGetCurrentIrql();
        if (irql >= DISPATCH_LEVEL){
            return;
        }    liInterval.QuadPart = -1 * (LONGLONG)50;    while (TRUE){
            BOOLEAN bBreak = TRUE;
            BOOLEAN bLockedResource = FALSE;
            BOOLEAN bLockedPagingIoResource = FALSE;
            bNeedReleaseResource = FALSE;
            bNeedReleasePagingIoResource = FALSE;        if (pFcb->PagingIoResource)
                bLockedPagingIoResource = ExIsResourceAcquiredExclusiveLite(pFcb->PagingIoResource);        if (pFcb->Resource){
                bLockedResource = TRUE;
                if (ExIsResourceAcquiredExclusiveLite(pFcb->Resource) == FALSE) {
                    bNeedReleaseResource = TRUE;
                    if (bLockedPagingIoResource) {
                        if (ExAcquireResourceExclusiveLite(pFcb->Resource, FALSE) == FALSE) {
                            bBreak = FALSE;
                            bNeedReleaseResource = FALSE;
                            bLockedResource = FALSE;
                        }
                    } else
                        ExAcquireResourceExclusiveLite(pFcb->Resource, TRUE);
                }
            }        if (bLockedPagingIoResource == FALSE) {
                if (pFcb->PagingIoResource){
                    bLockedPagingIoResource = TRUE;
                    bNeedReleasePagingIoResource = TRUE;
                    if (bLockedResource) {
                        if (!ExAcquireResourceExclusiveLite(pFcb->PagingIoResource, FALSE)){
                            bBreak = FALSE;
                            bLockedPagingIoResource = FALSE;
                            bNeedReleasePagingIoResource = FALSE;
                        }
                    } else {
                        ExAcquireResourceExclusiveLite(pFcb->PagingIoResource, TRUE);
                    }
                }
            }        if (bBreak) {
                break;
            }        if (bNeedReleasePagingIoResource) {
                ExReleaseResourceLite(pFcb->PagingIoResource);
            }
            if (bNeedReleaseResource){
                ExReleaseResourceLite(pFcb->Resource);
            }        if (irql == PASSIVE_LEVEL) {
                KeDelayExecutionThread(KernelMode, FALSE, &liInterval);
            } else {
                KEVENT waitEvent;
                KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
                KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, &liInterval);
            }
        }    if (pFileObject->SectionObjectPointer){
            IO_STATUS_BLOCK ioStatus;
            CcFlushCache(pFileObject->SectionObjectPointer, NULL, 0, &ioStatus);
            if (pFileObject->SectionObjectPointer->ImageSectionObject) {
                MmFlushImageSection(pFileObject->SectionObjectPointer,MmFlushForWrite); // MmFlushForDelete
            }
            CcPurgeCacheSection(pFileObject->SectionObjectPointer, NULL, 0, FALSE);
        }    if (bNeedReleasePagingIoResource){
            ExReleaseResourceLite(pFcb->PagingIoResource);
        }
        if (bNeedReleaseResource) {
            ExReleaseResourceLite(pFcb->Resource);
        }
    }