WinCE文件读写操作

WinCE文件读写操作


WinCE对文件操作有两种方式:一种是用WinCE自带的API函数,另一种方法是用MFC类库种的CFile类。

我们先用第一种的操作:

1.  文件的打开

HANDLE CreateFile(

LPCTSTR lpFileName,

DWORD dwDesireAccess,

DWORD dwShareMode,

LPSECURITY_ATTRIBUTES lpSecurityAttributes,

DWORD dwCreationDispostion,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile);

以上参数比较多,这个在EVC下有帮助,可以查到。可以举个例子:

HANDLE hFile;

hFile = CreateFile(_T(“//My Documents//MYFILE.TXT”), //创建 打开一个文件,串口,设备

GENERIC_READ,

FILE_SHARE_READ,//如果仅要求读访问,就打开该文件

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

If(hFile == INVALID_HANDLE_VALUE)

{

       AfxMessageBox(_T(“打开失败”));

       return;

}

2.  文件的关闭

文件使用完之后就应该及时关闭,以释放对它的资源

BOOL CloseHandle(HANDLE hObject);

比如说上例中

CloseHandle(hFile);

3.  文件的读写

文件的读

BOOL ReadFile(

HANDLE hFile,

LPVOID lpBuffer,//new BYTE[dwFileSize+1];

DWORD nNumberOfBytesToRead,//GetFileSize()

LPDWORD lpNumberOfBytesRead,

NULL);

最后一个参数在WINCE下是不支持的,所以一般用NULL.

文件的写

BOOL WriteFile(

HANDLE hFile,

LPCVOID lpBuffer,

DWORD nNumberOfBytesWritten,

NULL);

最后一个参数在WINCE下是不支持的,所以一般用NULL.

 

4.  文件指针的移动

DWORD SetFilePointer(

HANDLE hFile,

LONG lDistanceToMove,

PLONG lpDistanceToMoveHigh,

DWORD dwMoveMethod);

例如:

SetFilePointer(hFile,0,NULL,FILE_BEGIN);

 

5.  获取和设置文件信息

DWORD GetFileAtrribute(LPSTSTR lpFileName);//文件属性 比如:压缩,隐藏,只读等

参数表示文件名或者目录名

DWORD SetFileAttributes(LPCTSTR lpFileName,DWORD dwFileAttributes);

另外一个很重要的是:需要获取文件的编码方式,这个见下文:文本文件编码方式的简单识别 ,具体编程也很简单
   只需要 根据文件流的前4个字节判断Encoding

        //Unicode {0xFF, 0xFE};

        //BE-Unicode {0xFE, 0xFF};

        //UTF8 = {0xEF, 0xBB, 0xBF};



6.  获取和设置文件时间

BOOL GetFileTime(

HANDLE hFile,

LPFILETIME lpCreationTime,

LPFILETIME lpLastAccessTime,

LPFILETIME lpLastWriteTime);

BOOL SetFileTime(

HANDLE hFile,

const FILETIME *lpCreationTime,

const FILETIME *lpLastAccessTime,

const FILETIME *lpLastWriteTime);

7.  获取文件大小

DWORD GetFileSize(HANDLE hFile, NULL);

 

第二种操作:使用MFC

1.  文件的打开

CFile( LPCTSTR lpszFileName,  UNIT nOpenFlags);

或者使用CFile::Open函数

Virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError =NULL);

2.  文件的关闭

直接调用Close()方法就可以了,比如说file.Close();

3.  文件的读写

Virtual UNIT Read( void* lpBuf, UNIT nCount);

其中注意nCount是从文件中读取的最大的数据量,返回的是实际的读取的数据量,可能小于nCount的值。

Virtual void Write(const void * lpBuf, UNIT nCount);

4.  文件指针的移动

Virtual LONG Seek(LONG lOff, UINT nFrom); lOff表示偏移量,nFrom表示计算方式。

Void SeekToBegin();

Void SeekToEnd();


附1:

文本文件编码方式的简单识别
在实际编程中经常会碰到需要读取一个文本文件的内容并将其显示到程序中的情况。如果文件中所有的内容都以A SCII方式编码固然简单(通常包含英文字母和 数字的文件,比如readme之类),但遇到包含其他语言字符,如中文和日文之类就必须在显示之前知道其编码方式。这是因为很多程序在显示文本内容时只接 受UNICODE,故我们必须对非UNICODE的编码方式进行转换。由于谈到UNICODE时通常讨论的都是UCS-2,文中将只对UCS-2文件进行 分析。


(
参考:http://www.cnblogs.com/antony1029/archive/2008/09/29/1302009.html
当我们用System.IO.StreamReader读取包含汉字的txt文件时,经常会读出乱码(StreamWriater写文本文件也有类似的问题),原因很简单,就是文件的编码(encoding)和StreamReader/Writer的encoding不对应。


原理很简单,文本编辑器(比如XP自带的记事本)在生成文本文件时,如果编码格式和系统默认的编码(中文系统下默认为GB2312)不一致时,会在txt文件开头部分添加特定的“编码字节序标识(Encoding Bit Order Mark,简写为BOM)”,类似PE格式的"MZ"文件头。这样它在读取时就可以根据这个BOM来确定该文本文件生成时所使用的Encoding。这个BOM我们用记事本等程序打开默认是看不到的,但是用stream按字节读取时是可以读到的。


由于在GB2312和UTF7编码都没有BOM,所以需要指定一个默认的Encoding,在找不到合法的BOM时,将返回这个Encoding。有谁知道如何区分GB2312和UTF7编码txt文件的方法,也请告诉我。

)

本文提供了针对UCS-2 Little Endian,UTF-8和GB2312三种方式的文本文件进行编码识别的方法:

1. UCS-2文件

UCS-2 Little Endia文件 以FF FE开头,所以如果一个文件以该标志开头, 可以判断出其为UCS-2 Little Endian编码。类似的,UCS-2 Big Endia文件以FE FF开头。当读取UCS-2编码的大文件时,如果因为内存限制而无法一次性将所有内容都读出来的话,就需要分批读取。 由于UCS-2是长度固定的编码方式 (两个字节表示一个UNICODE字符),因此只要保证每次都采用偶数长度的缓冲区进行读取,转换就不会出现乱码

2. UTF-8文件

标 准UTF-8编码的文件是 以EF BB BF开头,如果读到该标志,则可以以UTF-8方式进行UCS-2的转码。但是当程序读取部分内容进行编码的时候则与UCS-2方式有很大的不同!根据规 范, 采用UTF-8方式进行编码的字符可以有从1到6个字节的不等长度。因此程序必须从缓冲区末尾开始判断最后一个UTF-8字符出现的位置,以防出现只 包含字符的部分内容从而导致转码失败。

UTF-8的编码规则如下表所示:

UCS-2取值范围 UTF-8编码格式
0x00000000 - 0x0000007F 0xxxxxxx
0x00000080 - 0x000007FF 110xxxxx 10xxxxxx    
0x00000800 - 0x0000FFFF         1110xxxx 10xxxxxx 10xxxxxx    
0x00010000 - 0x001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0x00200000 - 0x03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0x04000000 - 0x7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

因此逆向查找必须找到以下信息以确定UTF-8字符的开始字节:
  • ASCII兼容的字符。这种字符的UTF-8编码值小于0x7F
  • 非ASCII字符的UTF-8编码中的第一个字符总是在范围0xC0到0xFD。如果找到此范围内的字符,则可以确定一个UTF-8字符的开始。另外第一个编码的字节中1的个数指定了该字符总共的字节数。
这样就可以确定缓冲区的结尾是否包含了一个完整的UTF-8字符。如果只是部分包含,则应该将该字符去除,否则转换出的结果会有乱码。

3. GB2312文件

GB2312 为简体中文汉字的编码方式,在网络上很常见。GB2312编码的字符可以有一个或两个字节。其中和ASCII兼容的部分都占用一个字节。每个汉字由两个汉 字表示。GB2312的编码范围是0xA1A1-0x7E7E,去掉未定义的区域之后可以理解为实际编码范围是0xA1A1-0xF7FE。由于使用 GB2312编码的文件不像UCS-2或UTF-8一样使用特殊的标志,因此很难判断其编码方式。当然也可以采取猜测的方式,例如对于非ASCII的双字 节字符,其第一个字符处于0xA1到0x7E的范围之内。但这种方式并不保险,容易和其他编码方式冲突。

总之,对于不同编码方式的文件,除非有特殊的标志可以标示,否则只能采用猜测之类的办法,并且不能保证每次成功。估计只有等到未来UNICODE能够一统天下的时候才不会再有这些问题。:)


  附2:

fseek()

  此函数一般用于二进制模式打开的文件中,功能是定位到流中指定的位置,原型如下:

int fseek( FILE *stream, long offset, int origin );

如果成功返回0。

参数:

offset是移动的字符数,

origin是移动的基准,表示从哪开始移动文件指针,取值如下:

符号常量 基准位置
SEEK_SET 0 文件开头
SEEK_CUR 1 当前读写的位置
SEEK_END 2 文件尾部

例:fseek(file, 1000L, SEEK_CUR); //把读写位置从当前位置向后移动1234字节

  fseek(file, 0L, 2);  //把读写位置移动到文件尾

5、关闭则是使用fclose,原型如下:

int fclose( FILE *stream );

对这种方法,也给出几行简单代码:

FILE *fp = _wfopen(pFileName, L"ab");if (!fseek (fp, 100, SEEK_SET)){ x = fwrite(buffer, 1, 1024, fp); fflush (fp); }fclose (fp);


你可能感兴趣的:(WinCE文件读写操作)