/*******************************************************************************
* 函 数 名 : CopyAndConvertFile
* 描 述 : 文件复制,以字节方式复制,缓冲区越大速度越快.
* 输 入 : PUINT8 SrcFileName:
* 源文件名,支持路径分隔符和多级目录,字符串必须存放于RAM中
* PUINT8 TarFileName
* 目标文件名,支持路径分隔符和多级目录,字符串必须存放于RAM中
* 返 回 : 无.
*******************************************************************************/
UINT8 CopyAndConvertFile( PUINT8 SrcFileName, PUINT8 TarFileName )
{
UINT8 s;
UINT16 ThisLen, cnt;
UINT32 FileSize, ByteCount = 0;
UINT8 TarName;
UINT32 TarUpDirClust;
do
{
printf( "OpenSrc \n" ); /* 注意打印输出会浪费时间,减低平均复制速度 */
s = CH376FileOpenPath( SrcFileName ); /* 打开多级目录下的文件,输入缓冲区必须在RAM中 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
if ( ByteCount == 0 ) /* 首次 */
{
FileSize = CH376GetFileSize( ); /* 读取当前文件长度 */
printf( "SrcFileSz=%ld\n", FileSize );
}
else /* 再次进入 */
{
s = CH376ByteLocate( ByteCount ); /* 以字节为单位移动当前文件指针到上次复制结束位置 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
}
printf( "Read\n" );
s = CH376ByteRead( buf, sizeof( buf ), &ThisLen ); /* 以字节为单位从当前位置读取数据块,请求长度同缓冲区大小,返回实际长度在ThisLen中 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
for ( cnt = 0; cnt < ThisLen; cnt++ ) /* 将缓冲区中的小写字符转换为大写 */
{
s = buf[ cnt ];
if ( s >= 'a' && s <= 'z' )
{
buf[ cnt ] = s - ( 'a' - 'A' );
}
}
if ( ByteCount == 0 ) /* 首次,目标文件尚未存在 */
{
printf( "CreateTar\n" );
TarName = CH376SeparatePath( TarFileName ); /* 从路径中分离出最后一级文件名或目录名,返回最后一级文件名或目录名的偏移 */
if ( TarName ) /* 是多级目录 */
{
s = CH376FileOpenDir( TarFileName, TarName ); /* 打开多级目录下的最后一级目录,即打开新建文件的上级目录 */
if ( s != ERR_OPEN_DIR ) /* 因为是打开上级目录,所以,如果不是成功打开了目录,那么说明有问题 */
{
if ( s == USB_INT_SUCCESS )
{
return( ERR_FOUND_NAME ); /* 中间路径必须是目录名,如果是文件名则出错 */
}
else if ( s == ERR_MISS_FILE )
{
return( ERR_MISS_DIR ); /* 中间路径的某个子目录没有找到,可能是目录名称错误 */
}
else
{
return( s ); /* 操作出错 */
}
}
TarUpDirClust = CH376ReadVar32( VAR_START_CLUSTER ); /* 上级目录的起始簇号 */
}
else
{
TarUpDirClust = 0; /* 默认是根目录的起始簇号 */
}
/* 在当前目录下进行文件新建或者打开操作,比全路径多级目录下的文件新建或者打开操作的速度快,
所以目标文件的新建或者打开采用此法处理(本程序源文件是直接打开全路径多级目录下的文件,为提高速度,也可参照此法加快文件打开),
为了实现当前目录下的文件新建或者打开操作,参考上面几行代码,
首先,要获得文件所在的上级目录的起始簇号,相当于打开上级目录,通过CH376FileOpenPath打开上级目录获得,
其次,要获得文件的直接短文件名(去掉上级目录名,不含任何路径分隔符,保留最后一级文件名),通过CH376SeparatePath分析目标文件名获得 */
s = CH376FileCreate( &TarFileName[TarName] ); /* 在根目录或者当前目录下新建文件,如果文件已经存在那么先删除 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
}
else /* 再次进入,目标文件已存在 */
{
printf( "OpenTar\n" );
CH376WriteVar32( VAR_START_CLUSTER, TarUpDirClust ); /* 将目标文件所在的上级目录的起始簇号设置为当前簇号,相当于打开上级目录 */
s = CH376FileOpen( &TarFileName[TarName] ); /* 打开文件 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
s = CH376ByteLocate( ByteCount ); /* 以字节为单位移动当前文件指针到上次复制结束位置 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
}
printf( "Write\n" );
s = CH376ByteWrite( buf, ThisLen, NULL ); /* 以字节为单位向当前位置写入数据块,除非没有磁盘空间,否则返回实际长度总是与ThisLen相等 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
printf( "CloseTar\n" );
s = CH376FileClose( TRUE ); /* 关闭文件,对于字节读写建议自动更新文件长度 */
if ( s != USB_INT_SUCCESS )
{
return( s );
}
ByteCount += ThisLen;
if ( ThisLen < sizeof( buf ) ) /* 实际读出字节数小于请求读出字节数,说明原文件结束 */
{
if ( ByteCount != FileSize )
{
printf( "Error on SourceFile reading" );
}
break;
}
} while( ByteCount < FileSize );
return( USB_INT_SUCCESS );
}
|