how to split a file into pages and set each page address - c

My software needs to read a file and write to a device. It should split the file to smaller pages which has a maximum size (say M bytes), and also sets page address for each cycle. How can I implement it in C?
Thanks!
Hetty

It's not clear what are you going to do with this data but to read a file chunk by chunk you just need to use fread:
FILE *file = fopen("yourfile.dat", "rb");
size_t amount;
unsigned char buffer[PAGE_SIZE];
while ((amount = fread(buffer, 1, PAGE_SIZE, file)) > 0)
{
..
}

Related

Displaying content of file in C - write access error

I am trying to print the entire contents of a file in C that was stored in a previous function. The file size was read and dynamic memory allocation was used accordingly to create space relative to the file size. A pointer (fp) was then used to point to the newly allocated space. Then, the contents of the file were read into the new space. (I think this is where my error is).
// gloabl variables
unsigned char *fp = 0; //pointer to navigate through the opened file.
unsigned char *fileStart = 0; // pointer to save the start address of the file, in case you need to go back to start of file
unsigned char fileSize = 0; // stores the size of file
/* Use dynamic memory allocation to store the entire contents of the file and let that memory be pointed by 'fp'.
Save the start of file in 'fileStart' so that you use it to go to start of file in other functions.
After opening the file, read the file size and use it for dynamic memory allocation to read entire file. */
void loadFile(const char *filename)
{
FILE *p = fopen(filename, "rb");
if (p == NULL) {
printf("File not created, errno = %d\n", errno);
return 1;
}
fseek(p, 0, SEEK_END); // seek to end of file
fileSize = ftell(p); // get current file pointer
fseek(p, 0, SEEK_SET); // seek back to beginning of file
printf("File loaded. File size = %#x bytes\n", fileSize);
fp = malloc(fileSize + 1);
fread(fp, fileSize, 1, p);
fileStart = &fp;
fclose(p);
}
/*Display file in hex.
Display neatly the content of the file as seen in hex editor.
Even after closing the file with fclose(), we have the contents of the file in memory pointed by 'fp' (or 'fileStart' in loadFile()).
So you don't have to open and read the file again.*/
void displayBmpFile()
{
printf("Hex view of loaded bmp file: \n");
while(!feof(fileStart))
printf("%d\t", fgetc(fileStart));
}
I recognize the error is in my first function. First, I am not sure if the contents of the file were stored properly. If the contents were stored properly, is fp correctly pointing to the file? Lastly, if everything previously is working correctly, does fileStart correctly point to the beginning of the file?
(The file is a small hex file of four square colors).
change unsigned char fileSize = 0; to size_t fileSize = 0;
(your bitmap will surely be larger that 255 bytes.)
Then (2) in void displayBmpFile() do size_t n = fileSize; unsigned char *p = fileStart;and while (n--) printf("%hhu\t", *p++);

Reading a text file full with null characters and texts using fread

I am trying to design a small file system.
I have created a text file to store the files data in.
int kufs_create_disk(char* disk_name, int disk_size){
FILE* file_ptr = fopen(disk_name, "w");
if (file_ptr == NULL)
return -1;
fseek (file_ptr, disk_size * 1024-1, SEEK_SET);
fwrite("", 1, sizeof(char), file_ptr); // to make a size for the file
fclose(file_ptr);
DiskName=disk_name;
return 0;
}
After writing to the file I get a file with the size I determine when I call the function.
kufs_create_disk("test.txt", 5);
which creates a file with size of 5kbs with '\0' to fill this file to the size.
I have created another function to write to this file in different places of the file which works just fine and I won't paste the code for simplicity.
When I try to read from the file using fread(), I'm not getting all the data I have written into the memory; rather I get just some of the data.
My read implementation would be:
int kufs_read(int fd, void* buf, int n){
FILE *file_ptr= fopen("test.txt","a+");
fseek (file_ptr, FAT[fd].position, SEEK_SET); //where FAT[fd].position is where I want to start my read and fd is for indexing purposes
fread(buf, 1, n, file_ptr); //n is the number of bytes to be read
FAT[fd].position = FAT[fd].position + n;
}
The thing is the file reads some of the characters written and doesn't read the rest. I did a little test by looping all over the file and checking whether every thing is being read and fread reads every thing but in the buf I only get some of the characters I've written.
The text file looks something like this:
0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00written string1written string2 0\00\00\00\00\00\00\00\00\00\00\00\000\00\00\00\00\00\00\00\00\00\00\00\00writtenstring 3 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00
I get writtenstring1 and writtenstring2 in the buffer but I don't get writtenstring 3 for example.
Can you explain why?

pattern searching of binary data

I am trying to build antivirus in C.
I do that like this:
Read data of virus and picture file to scanned.
Check if virus data appear in picture data.
I read the data of scanned file and virus file like this: ( I read the file by binary mode because the file is picture(.png) )
// open file
file = fopen(filePath, "rb");
if (!file)
{
printf("Error: can't open file.\n");
return 0;
}
// Allocate memory for fileData
char* fileData = calloc(fileLength + 1, sizeof(char));
// Read data of file.
fread(fileData, fileLength, 1, file);
after i read the file data and the Virus data i check if the virus appear in the file like this:
char* ret = strstr(fileData, virusID);
if (ret != NULL)
printf("Infetecd file");
It does not work even though in my picture i have VirusID.
I want to check if the binary data of virus appear in binary data of picture.
For example: my binary data of my virus http://pastebin.com/xZbWA9qu
And the binary data of my picture(with the virus): http://pastebin.com/yjXr84kr
First, note the order of arguments of fread, fread(void *ptr, size_t size, size_t nmemb, FILE *stream); so to get the number of bytes, it's better to do fread(fileData, 1, fileLength, file);. Your code will return 0 or 1 depends on whether there is enough data to be read in the file, not the number of bytes it has read.
Second, strstr is to search for strings, not memory blocks, in order to search binary blocks, you need to write your own, or you can use the GNU extension function memmem.
// Allocate memory for fileData
char *fileData = malloc(fileLength);
// Read data of file.
size_t nread = fread(fileData, 1, fileLength, file);
void *ret = memmem(fileData, nread, virusID, virusLen);
if (ret != NULL)
printf("Infetecd file");
Search for the first byte of the virus signature, if you find it then see if the next byte is the second byte of the signature, and so on until you have checked and matched all bytes of the signature. Then the file is infected. If not all bytes matches then search again for the first byte of the signature.

Copying a file in C with fwrite

I am new to C and was trying to write a program just to copy a file so that I could learn the basics of files. My code takes a file as input, figures out its length by subtracting its start from its end using fseek and ftell. Then, it uses fwrite to write, based on what I could get from its man page, ONE element of data, (END - START) elements long, to the stream pointed to by OUT, obtaining them from the location given by FI. The problem is, although it does produce "copy output," the file is not the same as the original. What am I doing wrong? I tried reading the input file into a variable and then writing from there, but that didn't help either. What am I doing wrong?
Thanks
int main(int argc, char* argv[])
{
FILE* fi = fopen(argv[1], "r"); //create the input file for reading
if (fi == NULL)
return 1; // check file exists
int start = ftell(fi); // get file start address
fseek(fi, 0, SEEK_END); // go to end of file
int end = ftell(fi); // get file end address
rewind(fi); // go back to file beginning
FILE* out = fopen("copy output", "w"); // create the output file for writing
fwrite(fi,end-start,1,out); // write the input file to the output file
}
Should this work?
{
FILE* out = fopen("copy output", "w");
int* buf = malloc(end-start); fread(buf,end-start,1,fi);
fwrite(buf,end-start,1,out);
}
This isn't how fwrite works.
To copy a file, you'd typically allocate a buffer, then use fread to read one buffer of data, followed by fwrite to write that data back out. Repeat until you've copied the entire file. Typical code is something on this general order:
#define SIZE (1024*1024)
char buffer[SIZE];
size_t bytes;
while (0 < (bytes = fread(buffer, 1, sizeof(buffer), infile)))
fwrite(buffer, 1, bytes, outfile);
The first parameter of fwrite is a pointer to the data to be written to the file not a FILE* to read from. You have to read the data from the first file into a buffer then write that buffer to the output file. http://www.cplusplus.com/reference/cstdio/fwrite/
Perhaps a look through an open-source copy tool in C would point you in the right direction.
Here is How It can be done:
Option 1: Dynamic "Array"
Nested Level: 0
// Variable Definition
char *cpArr;
FILE *fpSourceFile = fopen(<Your_Source_Path>, "rb");
FILE *fpTargetFile = fopen(<Your_Target_Path>, "wb");
// Code Section
// Get The Size Of bits Of The Source File
fseek(fpSourceFile, 0, SEEK_END); // Go To The End Of The File
cpArr = (char *)malloc(sizeof(*cpArr) * ftell(fpSourceFile)); // Create An Array At That Size
fseek(fpSourceFile, 0, SEEK_SET); // Return The Cursor To The Start
// Read From The Source File - "Copy"
fread(&cpArr, sizeof(cpArr), 1, fpSourceFile);
// Write To The Target File - "Paste"
fwrite(&cpArr, sizeof(cpArr), 1, fpTargetFile);
// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);
// Free The Used Memory
free(cpArr);
Option 2: Char By Char
Nested Level: 1
// Variable Definition
char cTemp;
FILE *fpSourceFile = fopen(<Your_Source_Path>, "rb");
FILE *fpTargetFile = fopen(<Your_Target_Path>, "wb");
// Code Section
// Read From The Source File - "Copy"
while(fread(&cTemp, 1, 1, fpSourceFile) == 1)
{
// Write To The Target File - "Paste"
fwrite(&cTemp, 1, 1, fpTargetFile);
}
// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);

how to write .hex file on internal Flash ROM of microcontroller?

I want to write a ".hex" file of size 28 kb flash on to that Internal flashROM of size 32 kb.The above mentioned question is for initialising the flashROM. What i am doing for writing that file and the code is mentioned below:
I am having a .hex file in Intel hex format, that i have to read and write to internal
FlashROM of At91(8051) microcontroller.
Open the .hex file in "rb+" mode.
Get the length of the file and set the pointer to start address(zeroth address).
As I need to write that file page by page and pagesize in my case is 256 bytes, I have
divide the file by 256.
After that I have try to write that file.
Please let me know where I am going wrong. The code is given below.
int a,b; int size,last_chunk; FILE *file; char *buffer1,name[20]; unsigned long fileLen;
file = fopen("flashROM.hex", "rb+");
if (!file)
{
fprintf(stderr, "Unable to open file %s", name);
return;
}
fseek(file, 0, SEEK_END);
fileLen=ftell(file);
printf("the file length is:%d\n",fileLen);
fseek(file, 0, SEEK_SET);
//Allocate memory
buffer1 =(char *)malloc(fileLen+1);
if (!buffer1)
{
fprintf(stderr, "Memory error!");
fclose(file);
return;
}
//Read file contents into buffer
fread(buffer1, fileLen, 1, file);
/* We have to divide the entire file into chunks of 256 bytes*/
size = fileLen/256;
printf("\nsize = %d\n",size);
last_chunk = fileLen%256;
printf("\nlast chunk = %d bytes\n",last_chunk);
address = 0x0000;
printf("File upgradation should start from :%.4x",address);
for(a=0;a<=size;a++)
{
write(fd,&buffer1,size);
printf("Iteration=[%d]\t Data=[%x]\n",a,*buffer1);
usleep(5000);
}
for(b=0;b<=last_chunk;b++)
{
write(fd,&buffer1,1);
usleep(5000);
}
After executing the binary of above mentioned program, my result is mentioned below:
Writing upgrade file
the file length is:30855
size = 120
last chunk = 135 bytes
File upgradation should start from :0000
Iteration=[0] Data=[3a]
Iteration=[1] Data=[3a]
Iteration=[2] Data=[3a]
Iteration=[3] Data=[3a]
Iteration=[4] Data=[3a]
Iteration=[5] Data=[3a]
Iteration=[6] Data=[3a]
Iteration=[7] Data=[3a]
I don't know, why the data is always "3a", its not clear.
Please let me know where i have done wrong in programming.
You need a special tool that reads the .hex file and does whatever is necessary to write it into the flash memory of your controller (JTAG, talk to a bootloader via whatever means of communication, ...).
The tool depends on your specific microcontroller family. 8051 is not enough information, there is a huge variety of 8051s from many vendors.
Try using "wb+" as your mode for fopen
Opening the file as writable will create it if it doesn't already exist.
The code where you write data also looks suspect. You're passing a pointer to a pointer to a buffer into write rather than a simple pointer to your buffer. I also don't see the pointer getting incremented so you're writing the same data repeatedly.
You could try replacing your writing code with something like the following:
char* ptr = buffer1;
for(a=0;a<=size;a++)
{
write(fd,ptr,size);
ptr+=size;
printf("Iteration=[%d]\t Data=[%x]\n",a,*buffer1);
usleep(5000);
}
for(b=0;b<=last_chunk;b++)
{
write(fd,ptr,1);
usleep(5000);
}

Resources