Skip to content

Instantly share code, notes, and snippets.

@MurageKibicho
Created February 24, 2024 05:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MurageKibicho/c54cda5d9a29dfd08fb4c83301c2f57d to your computer and use it in GitHub Desktop.
Save MurageKibicho/c54cda5d9a29dfd08fb4c83301c2f57d to your computer and use it in GitHub Desktop.
Iterate through directory in C
#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