9275|36

79

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

应用程序如何读出SD卡里面一个较大文件 [复制链接]

这个问题比较可笑吧。
可是我就是搞不定,
现在网上down下了一个例子程序,是读出SD卡的一个test.txt文件。
  1. BOOL CSDMMCDlg::OnInitDialog()
  2. {
  3.         CDialog::OnInitDialog();

  4.         // Set the icon for this dialog.  The framework does this automatically
  5.         //  when the application's main window is not a dialog
  6.         SetIcon(m_hIcon, TRUE);                                // Set big icon
  7.         SetIcon(m_hIcon, FALSE);                        // Set small icon
  8.        
  9.         CenterWindow(GetDesktopWindow());        // center to the hpc screen

  10.         // TODO: Add extra initialization here
  11.         [color=#FF0000]m_strFileName = "test.txt";        [/color]                // 文件名
  12.         UpdateData(FALSE);

  13.         return TRUE;  // return TRUE  unless you set the focus to a control
  14. }


  15. // "创建文件/打开文件" 按键单击事件代码
  16. void CSDMMCDlg::OnCreateFile()
  17. {
  18.         CString filename = "";
  19.         UpdateData(TRUE);

  20.         if (m_strFileName == "")
  21.         {
  22.                 MessageBox(_T("请输入文件名!"));
  23.                 return;
  24.         }
  25.        
  26.         // 取得文件名及路径
  27.         filename = _T("\\Storage Card\") + m_strFileName;

  28.         // 创建一个文件或打开一个文件
  29.         hFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0,
  30.                                            NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  31.         if (hFile == INVALID_HANDLE_VALUE)
  32.         {
  33.                 MessageBox(_T("在SD/MMC卡上创建文件失败!"));
  34.                 return;
  35.         }

  36.         MessageBox(_T("成功创建/打开文件:") + filename);
  37. }

  38. // "读" 按键单击事件代码
  39. void CSDMMCDlg::OnReadfile()
  40. {
  41.         DWORD filelen,actlen;
  42.         char *pcharbuff;

  43.         if (hFile == INVALID_HANDLE_VALUE)
  44.         {
  45.                 MessageBox(_T("文件未打开!"));
  46.                 return;       
  47.         }
  48.        
  49.         filelen = GetFileSize(hFile, NULL);                                                        /* 获取文件大小 */
  50.         if (filelen == 0xFFFFFFFF)//文件为什么不能是4G?
  51.         {
  52.                 MessageBox(_T("获取文件大小失败!"));
  53.                 return;       
  54.         }

  55.         BOOL ret = SetFilePointer(hFile, 0, NULL, FILE_BEGIN);                /* 移动文件指针到文件开头 */       
  56.         if (ret == 0xFFFFFFFF)
  57.         {
  58.                 MessageBox(_T("将文件指针移至文件开头失败!"));
  59.                 return;       
  60.         }

  61.         pcharbuff = new char[filelen];
  62.         ret = ReadFile(hFile, pcharbuff, filelen, &actlen, NULL);        /* 从文件中读出数据 */
  63.         if (ret == TRUE)
  64.         {
  65.                 LPTSTR pStr = m_strDisp.GetBuffer(filelen);       
  66.                 // 将字节转化为 Unicode 字符串
  67.                 MultiByteToWideChar(CP_ACP, 0, pcharbuff, filelen, pStr, filelen);
  68.                 m_strDisp.ReleaseBuffer();
  69.                 UpdateData(FALSE);                                        /* 将读出的数据显示出来 */
  70.                 MessageBox(_T("读文件成功!"));       
  71.         }
  72.         else
  73.         {
  74.                 UpdateData(FALSE);
  75.                 MessageBox(_T("读文件失败!"));       
  76.         }

  77.         if (pcharbuff != NULL)
  78.                 delete[] pcharbuff;       
  79. }
复制代码


读txt等小文件是没有问题,但是当我把文件换成NK.nb0(30M)就读取失败了,怎么回事?
是不是new不能分配那么大的内存?
如果确实是这个原因,那应该怎么样做才能读出这么大的文件呢?
谢谢。

最新回复

这个神贴终于可以结了。。。。能update一个demo给我们看看就更好拉。哈哈哈  详情 回复 发表于 2008-12-9 12:49
点赞 关注

回复
举报

72

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
哈哈,怎么发了两个啊?

好正好散分,
大家帮帮忙解决一下。
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
我的平台是2440+64M SDRAM

这个new的内存应该是虚拟内存吧。

内存显示30M,估计被NK占用了30多M
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

4
 
这个思路就不对,应该是分段读,不能一次全部读到内存中。
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

5
 
我觉得有两个方法可以解决你的问题吧
1. 参考这个贴子,如何使用大于32M的内存,不过你的内存大小毕竟还是有限的,所以请参考第2个方法
http://topic.eeworld.net/u/20081126/17/0E05D29C-56C8-4A74-9077-CD7B8E50B653.html
2. 就是每次读固定大小的内容,比如1M,分多次读,然后做处理,这样的话无论多大的文件都可以处理
 
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

6
 
更新还真快,我去翻一下以前的旧贴子,都已经有好几个人回答问题了
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

7
 
引用 5 楼 hzdysymbol 的回复:
更新还真快,我去翻一下以前的旧贴子,都已经有好几个人回答问题了


哈哈,你最近好狠啊。分数涨的好快。看你上班貌似不用code的样子(*^__^*) 嘻嘻……
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

8
 
我一直写代码的,不过最近开始转做Android,现在主要还是学习
最近回答问题比较勤快,所以分数涨得挺快的
接下来可能要少上来一点了,上班时间基本就看看,不回答问题了
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

9
 
引用 6 楼 gooogleman 的回复:
引用 5 楼 hzdysymbol 的回复:
更新还真快,我去翻一下以前的旧贴子,都已经有好几个人回答问题了


哈哈,你最近好狠啊。分数涨的好快。看你上班貌似不用code的样子(*^__^*) 嘻嘻……

不过我看你学习还是很勤奋的,基本上都不休息,有前途
我每天除了上班干活,下班后从来不加班的
 
 
 

回复

53

帖子

0

TA的资源

一粒金砂(初级)

10
 
我是没有事情干,整天上网。
回家就上,不是电影就是论坛了。
以后不想这样了,生活太单调了。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 7 楼 hzdysymbol 的回复:
我一直写代码的,不过最近开始转做Android,现在主要还是学习
最近回答问题比较勤快,所以分数涨得挺快的
接下来可能要少上来一点了,上班时间基本就看看,不回答问题了


Android专门用在手机上的吗?

能不能弄到一些工控,PDA上,吗,。完全免费啊。
应用程序开发工具也配套?
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

12
 
代码是看完了。考虑用CFILE来处理下。可能会解决问题。换一个思路
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

13
 
如果文件太大,一次读不到内存中,还有一个问题就是SD卡中也应该是分段读取的。也要看驱动一次最多可以支持读取多大的数据块了。
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

14
 
不明白你什么意思,GOOOGLEMAN,你不是要在驱动中作优化吗?咋么跑应用层上来了,而且还是用的框架做的:)呵呵.如果是应用层来解决这个问题的话原则就是用哪段读哪段.不用的就释放.
ANDROID基本上是不推荐用到工控上来了,因为一开始的DESIGN就是为了给通讯设备用,关注用户体验,做UI极强,而且方便.不过实时性稳定性各方面应该没有太多保证:)如果你感兴趣可以和你私聊这个操作系统:)
 
 
 

回复

91

帖子

0

TA的资源

一粒金砂(初级)

15
 
引用 13 楼 BEYONDMA 的回复:
不明白你什么意思,GOOOGLEMAN,你不是要在驱动中作优化吗?咋么跑应用层上来了,而且还是用的框架做的:)呵呵.如果是应用层来解决这个问题的话原则就是用哪段读哪段.不用的就释放.
ANDROID基本上是不推荐用到工控上来了,因为一开始的DESIGN就是为了给通讯设备用,关注用户体验,做UI极强,而且方便.不过实时性稳定性各方面应该没有太多保证:)如果你感兴趣可以和你私聊这个操作系统:)


我一开始就是想用EVC的API函数啊。
谢谢。这个问题只是我没有做过,应该对做应用的是小问题。
我的和驱动打交道的部分还在后面,先弄这个应用的先。
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

16
 
  1. The following code example shows how to append one file to the end of another file. The example uses the CreateFile function to open two text (.txt) files: One.txt for reading and Two.txt for writing. Then, the example uses the ReadFile and WriteFile functions to append the contents of One.txt to the end of Two.txt by reading and writing 4-KB blocks.

  2. void AppendExample (void)
  3. {
  4.   HANDLE hFile, hAppend;
  5.   DWORD dwBytesRead, dwBytesWritten, dwPos;
  6.   char buff[4096];
  7.   TCHAR szMsg[1000];

  8.   // Open the existing file.

  9.   hFile = CreateFile (TEXT("\\ONE.TXT"),      // Open One.txt
  10.                       GENERIC_READ,           // Open for reading
  11.                       0,                      // Do not share
  12.                       NULL,                   // No security
  13.                       OPEN_EXISTING,          // Existing file only
  14.                       FILE_ATTRIBUTE_NORMAL,  // Normal file
  15.                       NULL);                  // No template file

  16.   if (hFile == INVALID_HANDLE_VALUE)
  17.   {
  18.     // Your error-handling code goes here.
  19.     wsprintf (szMsg, TEXT("Could not open ONE.TXT"));
  20.     return;
  21.   }

  22.   // Open the existing file, or, if the file does not exist,
  23.   // create a new file.

  24.   hAppend = CreateFile (TEXT("\\TWO.TXT"),      // Open Two.txt.
  25.                         GENERIC_WRITE,          // Open for writing
  26.                         0,                      // Do not share
  27.                         NULL,                   // No security
  28.                         OPEN_ALWAYS,            // Open or create
  29.                         FILE_ATTRIBUTE_NORMAL,  // Normal file
  30.                         NULL);                  // No template file

  31.   if (hAppend == INVALID_HANDLE_VALUE)
  32.   {
  33.     wsprintf (szMsg, TEXT("Could not open TWO.TXT"));
  34.     CloseHandle (hFile);            // Close the first file.
  35.     return;
  36.   }
复制代码


上面不是动态申请内存,也可以弄到4K,
不过我不懂每次读10K的话,我怎么找到原来文件读的位置。

请大家指点一下,这个EVC确实不懂用,
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

17
 
  1. 在网上找了很久找不到资料
  2. 在google里面输入read large file
  3. 才有
  4. http://blog.eeworld.net/EricYeung/archive/2008/07/16/2659574.aspx
  5. Use MemoryMapFile to read large file收藏
  6. 新一篇: C# join DataTable (support Left/Right/Full join) | 旧一篇: sql split path
  7. // FileMapTest.cpp : Defines the entry point for the console application.
  8. //

  9. #include "stdafx.h"
  10. #include "FileMapTest.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #endif

  14. #include "MtVerify.h"

  15. // The one and only application object

  16. CWinApp theApp;

  17. using namespace std;

  18. void ReadFileWithFileMap()
  19. {
  20.     DWORD dwStart = GetTickCount();

  21.     HANDLE hLargeFile = CreateFile("C:\\LargeFile.txt", GENERIC_READ,
  22.         FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  23.     MTVERIFY(hLargeFile != NULL);

  24.     HANDLE hFileMap = CreateFileMapping(hLargeFile, NULL, PAGE_READONLY,
  25.         0, 0, NULL);
  26.     MTVERIFY(hFileMap != NULL);

  27.     SYSTEM_INFO SysInfo;
  28.     GetSystemInfo(&SysInfo);
  29.     DWORD dwGran = SysInfo.dwAllocationGranularity;
  30.     DWORD dwFileSizeHigh;
  31.     __int64 qwFileSize = GetFileSize(hLargeFile, &dwFileSizeHigh);
  32.     qwFileSize |= (((_int64)dwFileSizeHigh) << 32);

  33.     CloseHandle(hLargeFile);

  34.     DWORD dwBlockBytes = dwGran * 1000;
  35.     if (dwBlockBytes > qwFileSize)
  36.         dwBlockBytes = (DWORD)qwFileSize;

  37.     printf("SysInfo.dwAllocationGranularity = %d, FileSize = %d, BlockBytes = %u\n",
  38.         dwGran, qwFileSize, dwBlockBytes);

  39.     TCHAR *lpbMapAddress = (TCHAR *)MapViewOfFile(hFileMap,
  40.         FILE_MAP_READ, 0, 0, dwBlockBytes);
  41.     MTVERIFY(lpbMapAddress != NULL);

  42.     //2007-08-17,09:45:13,20484.000000,20520.000000,20484.000000,20517.000000

  43.     TCHAR *pStart = strstr(lpbMapAddress, "2007-08-17");
  44.     TCHAR szData[1024];

  45.     if (pStart)
  46.     {
  47.         TCHAR *pEnd = strchr(pStart, '\n');
  48.         if (pEnd)
  49.         {
  50.             int nSize = pEnd - pStart;
  51.             if (nSize > 1024) nSize = 1024;
  52.             strncpy(szData, pStart, nSize);
  53.             szData[nSize-1] = '\0';
  54.             printf("Found data: %s\n", szData);
  55.         }
  56.     }

  57.     UnmapViewOfFile(lpbMapAddress);
  58.     CloseHandle(hFileMap);

  59.     DWORD dwMs = GetTickCount() - dwStart;
  60.     printf("Map test done, elapsed time = %d ms.\n", dwMs);
  61. }

  62. void ReadFileByLine()
  63. {
  64.     CStdioFile file;
  65.     CString str;
  66.     DWORD dwStart = GetTickCount();
  67.     if (file.Open("C:\\LargeFile.txt", CStdioFile::modeRead))
  68.     {
  69.         while(file.ReadString(str))
  70.         {
  71.             if(strncmp(str.GetBuffer(0), "2007-08-17", 10) == 0)
  72.             {
  73.                 printf("Found data: %s\n", str.GetBuffer(0));
  74.                 break;
  75.             }
  76.         }
  77.         file.Close();
  78.     }
  79.     DWORD dwMs = GetTickCount() - dwStart;
  80.     printf("Line-read test done, elapsed time = %d ms.\n", dwMs);
  81. }

  82. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  83. {
  84.     int nRetCode = 0;

  85.     // initialize MFC and print and error on failure
  86.     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  87.     {
  88.         // TODO: change error code to suit your needs
  89.         _tprintf(_T("Fatal Error: MFC initialization failed\n"));
  90.         nRetCode = 1;
  91.     }
  92.     else
  93.     {
  94.         // TODO: code your application's behavior here.
  95.         ReadFileWithFileMap(); //120 - 140 MS
  96.         printf("\n");
  97.         ReadFileByLine(); //2000+ MS
  98.     }

  99.     return nRetCode;
  100. }
复制代码
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

18
 
Memory-Mapped FilesWindows CE supports both named and unnamed file-mapping objects. Unnamed files provide a method both for interprocess communication and as a way to allocate virtual memory regions larger than the 32-MB slot size limit.

In Windows CE, unnamed, or page file backed, memory-mapped files are not backed up by a page file nor do they have to be unnamed. The name of this type of memory-mapped file comes from Windows NT where an application could use the paging file of the OS to create a huge, sparse array of virtual pages. The memory-mapped file was unnamed because it was not backed up by a real file on the disk. In Windows CE, the created object can have a name and that name can be passed to other processes so they can access the same object.

 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

19
 
引用 4 楼 hzdysymbol 的回复:
我觉得有两个方法可以解决你的问题吧
1. 参考这个贴子,如何使用大于32M的内存,不过你的内存大小毕竟还是有限的,所以请参考第2个方法
http://topic.eeworld.net/u/20081126/17/0E05D29C-56C8-4A74-9077-CD7B8E50B653.html
2. 就是每次读固定大小的内容,比如1M,分多次读,然后做处理,这样的话无论多大的文件都可以处理

照着hzdysymbol的提供帖子的方法来测试了一下,这样申请60M的内存成功了。
哎,付林林的文章居然说这下面函数是申请物理内存,真是非常令人失望——wince下怎么可能直接操作物理内存呢?难怪nbcool版主说付林林的文章很多错误了。
// "读" 按键单击事件代码
  1. void CSDMMCDlg::OnReadfile()
  2. {
  3.         //------------alloc large memery test-----------------
  4.         LPBYTE pBuffer = NULL;
  5.         DWORD dwTotalSize = 60*1024*1024;
  6.         HANDLE hFileMap = NULL;

  7.         hFileMap = CreateFileMapping ((HANDLE)-1, NULL, PAGE_READWRITE, 0, dwTotalSize, 0);
  8.         if (hFileMap)
  9.         {
  10.                 pBuffer = (LPBYTE)MapViewOfFile (hFileMap, FILE_MAP_WRITE, 0, 0, 0);
  11.                 if (pBuffer)
  12.                 {
  13.                         MessageBox(_T("申请大容量60M内存成功!"));
  14.                 //
  15.                 // Use the data in the file.
  16.                 //

  17.                 // Start cleanup by unmapping view.
  18.                         UnmapViewOfFile (pBuffer);
  19.                         pBuffer = NULL;
  20.                 }
  21.                 CloseHandle (hFileMap);
  22.                 hFileMap = NULL;
  23. }

  24. }
复制代码
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

20
 
这样分配成功了也不一定能保证正确使用,只是分配了60M的虚拟空间地址,相当于MEM_RESERVE
并没有对应到实际物理内存,当用到那一片内存的时候才会去MEM_COMMIT
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表