fileutil.c

来自「傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。」· C语言 代码 · 共 476 行

C
476
字号
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <crblib/inc.h>
#include <crblib/strutil.h>
#include <crblib/fileutil.h>
#include <io.h>

#include <sys/utime.h>

void dprintf(const char * String, ...)
{
	va_list			ArgPtr;
    char			TempStr[4096];

	va_start(ArgPtr, String);
    vsprintf(TempStr, String, ArgPtr);
	va_end(ArgPtr);

	if ( isatty(_fileno(stdout)) )
		printf(TempStr);
	else
	{
		printf(TempStr);
		fprintf(stderr,TempStr);
	}
}

ubyte * readFile(char *name)
{
int len;
return readFile2(name,&len);
}

ubyte * readFile2(char *name,int *lenptr)
{
ubyte *buf;
ulong len;
FILE *fp;

	if ( (fp = fopen(name,"rb")) == NULL )
		return NULL;

	*lenptr = -1;

	if ( (len = FileLengthofFH(fp)) == FileLengthofFH_Error ) {
		fclose(fp);
		return NULL;
	}

	if ( (buf = malloc(len)) == NULL ) {
		fclose(fp);
		return NULL;
	}

	FRead(fp,buf,len);

	fclose(fp);

	*lenptr = len;

return buf;
}

bool writeFile(char *name,ubyte *buf,int len)
{
FILE * f;
	f = fopen(name,"wb");
	if ( ! f ) return false;

	if ( ! FWriteOk(f,buf,len) )
	{
		fclose(f);
		return false;
	}

	fclose(f);
return true;
}

/* endian-independent Number IO */

ulong fgetul(FILE *FP)
{
ulong ret;
ret  = fgetc(FP); ret<<=8;
ret += fgetc(FP); ret<<=8;
ret += fgetc(FP); ret<<=8;
ret += fgetc(FP);
return(ret);
}
void  fputul(ulong v,FILE *FP)
{
fputc((v>>24)&0xFF,FP);
fputc((v>>16)&0xFF,FP);
fputc((v>> 8)&0xFF,FP);
fputc((v    )&0xFF,FP);
}

uword fgetuw(FILE *FP)
{
uword ret;
ret  = (fgetc(FP)<<8);
ret += fgetc(FP);
return(ret);
}
void  fputuw(uword v,FILE *FP)
{
fputc(v>>8,FP);
fputc(v&0xFF,FP);
}

uword fgetuwi(FILE *FP)
{
uword ret;
ret = fgetc(FP);
ret += (fgetc(FP)<<8);
return(ret);
}
void  fputuwi(uword v,FILE *FP)
{
fputc(v&0xFF,FP);
fputc(v>>8,FP);
}

ubyte fgetub(FILE *FP) { return fgetc(FP); }
void  fputub(ubyte v,FILE *FP) { fputc(v,FP); }

/**

only Amiga and PC paths are supported! no UNIX no Mac !

this doesn't affect you if you don't use CatPaths() or FilePart()
	or libs that use them, such as Walker()

**/

/***************/

char * FilePart(char *F);
void DrivePartInsert(char *Name,char *PutIn);

/***************/

void printcommas(FILE * tofile,ulong num)
{
char tempstr[20];
strcommas(tempstr,num);
fprintf(tofile,tempstr);
}

void CutEndPath(char *Path)
{
char * EndBase = &Path[strlen(Path)-1];
if ( *EndBase == PathDelim ) *EndBase = 0;
return;
}

void CatPaths(char *Base,char *Add)
{
char * EndBase = &Base[strlen(Base)-1];

if ( *EndBase != ':' && *EndBase != PathDelim )
	{
	EndBase++;
	*EndBase++ = PathDelim;
	*EndBase = 0;
	}
strcat(EndBase,Add);
}

/** this func works even when AddTo has backwards-path
				components. i.e. it works as a full 'cd' :
		PrefixCurDir("/") or PrefixCurDir("..\..") work fine

		note : if you are in a drive, and you do cd("/") you will
			go up one dir - to the null path, which on the Amiga is
			your boot drive.  I'm not sure what the null path is under
			WinNT, but it would be nice if it were the My Computer thing.
	**/

void PrefixCurDir(char *AddTo)
{
char CurDir[2048];
char * AddToPtr;

getcwd(CurDir,1024);

if ( *AddTo == ':' || *AddTo == '\\' )
	{
	AddToPtr = CurDir + 1024;
	strcpy(AddToPtr,AddTo+1);
	DrivePartInsert(CurDir,AddTo);
	strcat(AddTo,AddToPtr);
	return;
	}
if ( *CurDir == 0 ) return;

if ( strchr(AddTo,':') )
  return;
#if 0	// change to dir of given path
  {
	char Work[1024];

  PathPartInsert(AddTo,Work);
  if ( chdir(Work) == 0 )
    {
    if ( getcwd(Work,1024) )
			{
	  	CatPaths(Work,FilePart(AddTo));
  		strcpy(AddTo,Work);
			}
		}
	return;
  }
#endif

CatPaths(CurDir,"");

AddToPtr = AddTo;

while ( *AddToPtr == '/' || ( AddToPtr[0] == '.' && AddToPtr[1] == '.' ) )
	{
	if ( *AddToPtr == '/' ) AddToPtr++;
	else
		{
		AddToPtr += 2;
		if ( *AddToPtr == '\\' ) AddToPtr++;
		}

	*(CurDir+strlen(CurDir)-1) = 0; /* cut off path delim */
	*(FilePart(CurDir)) = 0; /* cut one dir */

	if ( *CurDir == 0 ) return;
	}

while ( AddToPtr[0] == '.' && AddToPtr[1] == '\\' )
	{
	AddToPtr += 2;
	}

strcat(CurDir,AddToPtr);
strcpy(AddTo,CurDir);
}

ulong FileLengthofFH(FILE * fh)
{
long start,end;
start = ftell(fh);
fseek(fh,0,SEEK_END);
end = ftell(fh);
fseek(fh,start,SEEK_SET);
return((ulong)end);
}


ulong fileLength(char *name)
{
FILE * fp;
ulong len = FileLengthofFH_Error;

	if ( (fp = fopen(name,"rb")) == NULL )
		return len;

	len = FileLengthofFH(fp);

	fclose(fp);

return len;
}

void DrivePartInsert(char *Name,char *PutIn)
{
char * P;

strcpy(PutIn,Name);

if ( ( P = strchr(PutIn,':') ) == NULL )
	*PutIn = 0;

P++;
#ifndef _AMIGA
if ( *P == '\\' ) P++;
#endif

*P = 0;
}

char DrivePartRet[1024];
char * DrivePart(char *F)
{
DrivePartInsert(F,DrivePartRet);
return(DrivePartRet);
}

void PathPartInsert(char *F,char *Insert)
{
char * FP;
strcpy(Insert,F);
FP = FilePart(Insert);
if ( FP ) *FP = 0; 
return;
}

char PathPartRet[1024];
char * PathPart(char *F)
{
PathPartInsert(F,PathPartRet);
return(PathPartRet);
}

char * FilePart(char *F)
{
char *a;

if ( a = strrchr(F,PathDelim) )
	return(a+1);

if ( a = strrchr(F,':') )
	return(a+1);

return(F);
}

bool FileExists(char *Name)
{
struct stat st;

if ( stat(Name,&st) == 0 ) return(1);

return(0);
}

bool NameIsDir(char *Name)
{
struct stat st;
char * NamePath;

if ( stat(Name,&st) == 0 )
	{
	if ( S_ISDIR(st.st_mode) ) return(1);
	return(0);
	}

if ( NamePath = malloc(strlen(Name)+1) )
	{
  strcpy(NamePath,Name);
  CutEndPath(NamePath);
	
	if ( stat(NamePath,&st) == 0 )
		{
		if ( S_ISDIR(st.st_mode) )
			{
			CatPaths(NamePath,"");
			if ( strcmp(NamePath,Name) == 0 )
				{
				free(NamePath);
				return(1);
				}
			}
		}
	free(NamePath);
	}

return(0);
}

#ifdef _MSC_VER //{ // direct functions , msc doesn't provide these !! assholes
#include <io.h>

struct DIR
{
	long handle;
	struct _finddata_t data;
	struct dirent entry;
	bool didFirst;
};

int	closedir( DIR * d )
{
	_findclose(d->handle);
	destroy(d);
return 0;
}

DIR	*opendir( const char * name )
{
DIR * d;
char tempName[1024];
	d = new(DIR);
	if ( ! d ) return NULL;
	strcpy(tempName,name);
	CatPaths(tempName,"*");
	d->handle = _findfirst(tempName,&(d->data));
	if ( d->handle == -1 )
	{
		destroy(d);
		return NULL;
	}
	strcpy(d->entry.d_name,d->data.name);
	d->didFirst = true;
return d;
}

struct dirent *readdir( DIR * d )
{
if ( ! d ) return NULL;
else
	{
	struct dirent * ret = &(d->entry);

	if ( d->didFirst )
		d->didFirst = false;
	else
		if ( _findnext(d->handle,&(d->data)) == 0 )
			strcpy(d->entry.d_name,d->data.name);
		else
			return NULL;
	return ret;
	}
}

#else //}{ not MSVC

#endif //} MSVC

bool copystat(const char * tofile,const char *fmfile)
{
struct stat s;
	if ( stat(fmfile,&s) != 0 )
		return false;
return setstat(tofile,&s);
}

bool setstat(const char * file,const struct stat *s)
{
struct utimbuf ut;

	chmod(file,S_IREAD|S_IWRITE|S_IEXEC);

	ut.actime  = s->st_atime;
	ut.modtime = s->st_mtime;
	if ( utime(file, &ut) != 0 )
	{
		switch(errno)
		{
		case EACCES:
			errputs("utime failed : access denied");
			break;
		case EINVAL:
			errputs("utime failed : invalid date");
			break;
		case EMFILE:
			errputs("utime failed : too many files open !?");
			break;
		case ENOENT:
			errputs("utime failed : target file not found");
			break;
		default:
			errputs("utime failed : unknown error");
			break;
		}

		return false;
	}

	if ( chmod(file, s->st_mode ) != 0 )
		return false;

return true;
}

/****/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?