none
Wince文件系统一个奇怪的现象 RRS feed

  • 问题

  • 最近在做Wince5.0 SD卡的驱动,捣鼓了半个月,驱动做好了,文件的写入和读出都没问题,本来打算压力测试完毕后就结束这个工程,不料在进行压力测试的时候出现了问题。
    我的测试分为两种,分别为进行大文件写入读取和批量文件写入和读取,在做批量文件写入和读取的时候发现一个很奇观的问题,大家往下看。。。

    我的测试用例是这样的:通过一个循环向SD卡写入1000个4K大小的文件,但是每次写到999个文件的时候就出现错误,最后一个文件无法Create,错误码是0x70,查了一下Error Code的定义,这个错误是指磁盘没有足够的空间,但事实上我的SD卡容量是16GB的,1000个4K文件只有不足4MB大小,不可能出现这个错误。刚开始我以为是驱动做的不好造成的,但是当我把这个测试用例用在Nand Flash和U盘上面进行测试,同样的错误也出现了。U盘的驱动用的是微软的Storage Class Driver + OHCI,不应该有问题,假如有bug也不可能这么巧和我自己做的SDIO驱动出现相同的bug。
    不知道有没有朋友遇到这个问题?下面是我测试用例的一小段代码,大伙给瞧瞧:

    for(DWORD dwIndex = 0; dwIndex < 1000; dwIndex ++){
        memset(fileName, '\0', sizeof(fileName));
        wsprintf(fileName, TEXT("\\Storage Card\\file_%04d.o"), dwIndex);
        fileHandle = CreateFile(...);
        if(fileHandle == INVALID_HANDLE_VALUE){
            ...
            break;
        }
        if(!WriteFile(fileHandle,... ...)){
            ...
            break;
        }
        if(fileHandle){
              CloseHandle(fileHandle);
        }
    }
    不知是我的测试用例有问题还是CE的文件系统有问题。。。

    2009年10月27日 2:03

答案

  • 我认为U盘上面进行测试的问题应该在于你的压力测试压力实在太大了,
    我也发现微软提供的驱动确实存在类似的问题,但不是磁盘空间不够,而是驱动挂了.
    但我觉得这并不奇怪,微软只是提供实例给你,
    关键是你制定压力测试时和合格标准是什么?就如不是每楼楼房都必须具备抵抗8级以上地震的能力一样
    如果你需要它可以备抵抗8级以上地震的能力,可能要做特别的优化。
    建议请在每次写完文件后在系统刷新缓冲时,稍做休息:
    在此提供如下测试代码, 连续写1000个文件,每个文件4.2KB,没有任何问题

    //strLog = "..................."   //大小4KB

    //AfxMessageBox(_T("Test Start!"));
     
    CString strPath = _T("\\硬盘\\"); //CE目录,默认为"\HardDisk"
    //strPath = strPath + _T("Test.log"); //文件名(绝对路径)
     CFileException ex;
     CString strFile,strTmp;
     for (DWORD dwNum = 0; dwNum < 1000; dwNum++)
     { 
      strFile.Format(_T("Test%d.log"),dwNum);
      strFile = strPath + strFile; 

      //判断文件是否存在
      WIN32_FIND_DATA fd; 
      HANDLE hFind = FindFirstFile(strFile, &fd);
      if ((hFind != INVALID_HANDLE_VALUE)
       && !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
      { 
       FindClose(hFind);
       CFileStatus fileStat;
       memset(&fileStat,0,sizeof(CFileStatus));
       CFile::GetStatus(strFile,fileStat);
       CFile::Remove(strFile);
      }
      
      CFile f;
      if(!f.Open(strFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite,&ex))
      { 
       ASSERT(FALSE);
       TCHAR  szCause[255];
       CString strFormatted;
          
       ex.GetErrorMessage(szCause, 255);
       
       strFormatted.Format(_T("Create Log File Error %d - "),dwNum);
       strFormatted += szCause;
       TRACE(strFormatted + _T("\n"));
       return ;
      }
      
      f.Write(strLog,strLog.GetLength()*2);
      
      f.Flush();
      f.Close();
      
      Sleep(300);   //关键步骤
     }

     AfxMessageBox(_T("Test End!"));

    2009年10月27日 17:41

全部回复

  • 我认为U盘上面进行测试的问题应该在于你的压力测试压力实在太大了,
    我也发现微软提供的驱动确实存在类似的问题,但不是磁盘空间不够,而是驱动挂了.
    但我觉得这并不奇怪,微软只是提供实例给你,
    关键是你制定压力测试时和合格标准是什么?就如不是每楼楼房都必须具备抵抗8级以上地震的能力一样
    如果你需要它可以备抵抗8级以上地震的能力,可能要做特别的优化。
    建议请在每次写完文件后在系统刷新缓冲时,稍做休息:
    在此提供如下测试代码, 连续写1000个文件,每个文件4.2KB,没有任何问题

    //strLog = "..................."   //大小4KB

    //AfxMessageBox(_T("Test Start!"));
     
    CString strPath = _T("\\硬盘\\"); //CE目录,默认为"\HardDisk"
    //strPath = strPath + _T("Test.log"); //文件名(绝对路径)
     CFileException ex;
     CString strFile,strTmp;
     for (DWORD dwNum = 0; dwNum < 1000; dwNum++)
     { 
      strFile.Format(_T("Test%d.log"),dwNum);
      strFile = strPath + strFile; 

      //判断文件是否存在
      WIN32_FIND_DATA fd; 
      HANDLE hFind = FindFirstFile(strFile, &fd);
      if ((hFind != INVALID_HANDLE_VALUE)
       && !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
      { 
       FindClose(hFind);
       CFileStatus fileStat;
       memset(&fileStat,0,sizeof(CFileStatus));
       CFile::GetStatus(strFile,fileStat);
       CFile::Remove(strFile);
      }
      
      CFile f;
      if(!f.Open(strFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite,&ex))
      { 
       ASSERT(FALSE);
       TCHAR  szCause[255];
       CString strFormatted;
          
       ex.GetErrorMessage(szCause, 255);
       
       strFormatted.Format(_T("Create Log File Error %d - "),dwNum);
       strFormatted += szCause;
       TRACE(strFormatted + _T("\n"));
       return ;
      }
      
      f.Write(strLog,strLog.GetLength()*2);
      
      f.Flush();
      f.Close();
      
      Sleep(300);   //关键步骤
     }

     AfxMessageBox(_T("Test End!"));

    2009年10月27日 17:41
  • Windows CE 在一个目录下最多能存储 999 个具有相同短文件名(即 8 个字符的名称、句点 (.) 和 3 个字符的扩展名)的文件。解决方法是确保短文件名不同。例如,如果将文件命名为 Longfilename1000.txt 到 Longfilename0001.txt,请将数字放在文件名的开头而不是结尾。 http://msdn.microsoft.com/zh-cn/library/system.io.filemode(VS.90).aspx
    2010年5月28日 8:54