Created
February 24, 2024 05:33
-
-
Save MurageKibicho/c54cda5d9a29dfd08fb4c83301c2f57d to your computer and use it in GitHub Desktop.
Iterate through directory in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#include <assert.h> | |
#include <dirent.h> | |
#include <string.h> | |
#include <sys/stat.h> | |
#define MAX_LENGTH 256 | |
//Ben | |
int CountNumberOfFiles(char *path) | |
{ | |
int result = 0; | |
DIR *directory = opendir(path); | |
assert(directory != NULL); | |
struct dirent *directoryEntry; | |
while((directoryEntry = readdir(directory)) != NULL) | |
{ | |
if(directoryEntry->d_name[0] != '.') | |
{ | |
int fileNameLength = (int)sizeof(directoryEntry->d_name); | |
assert(fileNameLength <= MAX_LENGTH); | |
result++; | |
} | |
} | |
closedir(directory); | |
return result; | |
} | |
void PrintFileNames(char **fileNames, int fileCount) | |
{ | |
for(int i = 0; i < fileCount; i++) | |
{ | |
printf("%s\n", fileNames[i]); | |
} | |
} | |
void DestroyFileNames(char **fileNames, int fileCount) | |
{ | |
for(int i = 0; i < fileCount; i++) | |
{ | |
free(fileNames[i]); | |
} | |
free(fileNames); | |
} | |
void SortFileNames(char **fileNames, int fileCount) | |
{ | |
char temporary[MAX_LENGTH] = {0}; | |
for(int k = 0; k < fileCount; k++) | |
{ | |
for(int j = k + 1; j < fileCount; j++) | |
{ | |
if(strcasecmp(fileNames[k], fileNames[j]) > 0) | |
{ | |
strcpy(temporary, fileNames[k]); | |
strcpy(fileNames[k], fileNames[j]); | |
strcpy(fileNames[j], temporary); | |
memset(temporary,0,MAX_LENGTH); | |
} | |
} | |
} | |
} | |
char **GetFileNames(char *path, int *fileCount) | |
{ | |
//Count files and ensure length <= 256 | |
*fileCount = CountNumberOfFiles(path); | |
//Array to store file names | |
char **result = malloc(*fileCount * sizeof(char*));for(int i = 0; i < *fileCount; i++){result[i] = calloc(MAX_LENGTH, sizeof(char));} | |
//Get file names | |
DIR *directory = opendir(path); | |
assert(directory != NULL); | |
struct dirent *directoryEntry; | |
int currentIndex = 0; | |
while((directoryEntry = readdir(directory)) != NULL){if(directoryEntry->d_name[0] != '.'){for(int i = 0; i < MAX_LENGTH; i++){result[currentIndex][i] = directoryEntry->d_name[i];}currentIndex++;}} | |
//Sort array | |
SortFileNames(result, *fileCount); | |
closedir(directory); | |
return result; | |
} | |
char *CreateStorageDirectory(char *path) | |
{ | |
char outputFolder[MAX_LENGTH] = {0}; | |
snprintf(outputFolder, sizeof(outputFolder), "%s_Headless",path); | |
DIR *directory = opendir(outputFolder); | |
if(directory == NULL) | |
{ | |
int outputFolderCreationSuccess = mkdir(outputFolder,0777); | |
assert(outputFolderCreationSuccess == 0); | |
} | |
else | |
{ | |
closedir(directory); | |
} | |
char *result = calloc(MAX_LENGTH, sizeof(char)); | |
for(int i = 0; i < MAX_LENGTH; i++){result[i] = outputFolder[i];} | |
return result; | |
} | |
int FindFileSize(char *fileName) | |
{ | |
int result = 0; | |
FILE *fp = fopen(fileName, "rb");assert(fp != NULL); | |
fseek(fp, 0L, SEEK_END); | |
result = ftell(fp); | |
rewind(fp); | |
fclose(fp); | |
return result; | |
} | |
double CalculateEntropy(int *frequencies, int max) | |
{ | |
double sum = (double) max; | |
double entropy = 0; | |
for(int i = 0 ; i < MAX_LENGTH; i++) | |
{ | |
double probability = ((double)frequencies[i])/ sum; | |
if(probability > 0) | |
{ | |
entropy += probability * log2(probability); | |
} | |
} | |
return -entropy; | |
//printf("(%.3f)\n",-entropy); | |
} | |
int FindHeaderSize(char *fileName) | |
{ | |
int result = 0; | |
int frequencies[MAX_LENGTH] = {0}; | |
FILE *fp = fopen(fileName, "rb");assert(fp != NULL); | |
int c = 0; | |
long count = 0; | |
int j = 1; | |
double entropy = 0; | |
while((c = fgetc(fp)) != EOF) | |
{ | |
frequencies[c] += 1; | |
if(count == (1L << j)) | |
{ | |
entropy = CalculateEntropy(frequencies,count); | |
if(entropy >= 7.9){break;} | |
//printf("(%d: %ld %.1f)\n",j,count,entropy); | |
j++; | |
} | |
count++; | |
} | |
//printf("(%d: %ld)\n",j,count); | |
fclose(fp); | |
result = j-1; | |
if(result < 0){result = 0;} | |
return result; | |
} | |
int StoreFile(char *inputFileName, int headerSize, FILE *header, FILE* output) | |
{ | |
printf("%s\n",inputFileName); | |
FILE *fp = fopen(inputFileName, "rb"); assert(fp != NULL); | |
int c = 0; | |
long count = 0; | |
assert(headerSize < 256); | |
unsigned char firstByte = (unsigned char) headerSize; | |
fwrite(&firstByte, 1 , sizeof(unsigned char), header); | |
while((c = fgetc(fp)) != EOF) | |
{ | |
if(count == (1L << headerSize)) | |
{ | |
printf("%ld %dZ",count,headerSize); | |
break; | |
} | |
fputc(c, header); | |
count++; | |
} | |
while((c = fgetc(fp)) != EOF) | |
{ | |
fputc(c, output); | |
} | |
fclose(fp); | |
} | |
void EncodeFolder(char *outputFolder, char *path, char **fileNames, int fileCount) | |
{ | |
//printf("Folder name: %s\n",outputFolder); | |
char headerDataName[MAX_LENGTH] = {0}; | |
char outputFileName[MAX_LENGTH] = {0}; | |
char inputFileName[MAX_LENGTH] = {0}; | |
snprintf(headerDataName, sizeof(headerDataName), "%s/%s.headers",outputFolder,path); | |
//printf("Folder name: %s\n",offsetsName); | |
FILE *header = fopen(headerDataName, "wb");assert(header != NULL); | |
int fileSize = 0; | |
int headerSize = 0; | |
for(int i = 0; i < fileCount; i++) | |
{ | |
snprintf(inputFileName, sizeof(inputFileName), "%s/%s",path, fileNames[i]); | |
snprintf(outputFileName, sizeof(outputFileName), "%s_Headless/%s.headless",path,fileNames[i]); | |
FILE *output = fopen(outputFileName, "wb");assert(output != NULL); | |
headerSize = FindHeaderSize(inputFileName); | |
printf("(%d) ", headerSize); | |
StoreFile(inputFileName,headerSize, header, output); | |
memset(inputFileName,0,MAX_LENGTH); | |
memset(outputFileName,0,MAX_LENGTH); | |
fclose(output); | |
} | |
fclose(header); | |
} | |
int main() | |
{ | |
char *path="Pics";assert(path[0]!= '.'); | |
int fileCount = 0; | |
char **fileNames = GetFileNames(path, &fileCount);assert(fileNames != NULL); | |
char *outputFolder = CreateStorageDirectory(path); | |
EncodeFolder(outputFolder,path, fileNames, fileCount); | |
DestroyFileNames(fileNames, fileCount); | |
free(outputFolder); | |
return 0; | |
} | |
//Buford, Lawrencville Georgia |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment