Write in a loop into a buffer as binary file (.ts) - c

I a trying to write data into a .ts file continuously in c programming.
File Source: on streaming video
File destination: /cache/test/pull_data.ts
output: file size like below
in 1st iteration pull_data.ts --> file size 1213 bytes
in 2nd iteration pull_data.ts --> file size 1213 + 1213 bytes
in 3ed iteration pull_data.ts --> file size 1213 + 1213 +1213 bytes , --- and so on.
I have written code like below:
#define data_size 1213;
unsigned char sourcebuf[data_size + 1];
int source_size = 0;
FILE * fileopen;
fileopen = fopen("/cache/test/pull_data.ts ", "wb");
if (fileopen == NULL) {
printf("error : pull_data.ts opening file ");
exit(1);
} else {
printf("sucesses : pull_data.ts opening file ");
fwrite(sourcebuf, source_size, 1, fileopen);
}
We use it to get the data continuously from the source. but for me, pull_data.ts size is always showing 1213 bytes. How could I loop this function to update -- > current data + comming data in the pull_data.ts file?

The error is in the mode parameter, as the commentors have already told you.
By putting wb, as specified in the documentation of fopen, you are telling fopen to discard any previous content of the file and start from the beginning instead.
What you want, is the mode parameter ab (a for 'append') instead, which will open the file and put the write pointer to the end of the file.
The b in there means 'binary' which translates to 'Do not treat \n in any special way', which is a very good idea if you're dealing with binary files.
There are a number of other flags as well, such as a+ (open for appending and reading), r for readonly and r+ for reading and writing. All of these will open the file, leaving the contents intact.

Related

How to duplicate an image file? [duplicate]

I am designing an image decoder and as a first step I tried to just copy the using c. i.e open the file, and write its contents to a new file. Below is the code that I used.
while((c=getc(fp))!=EOF)
fprintf(fp1,"%c",c);
where fp is the source file and fp1 is the destination file.
The program executes without any error, but the image file(".bmp") is not properly copied. I have observed that the size of the copied file is less and only 20% of the image is visible, all else is black. When I tried with simple text files, the copy was complete.
Do you know what the problem is?
Make sure that the type of the variable c is int, not char. In other words, post more code.
This is because the value of the EOF constant is typically -1, and if you read characters as char-sized values, every byte that is 0xff will look as the EOF constant. With the extra bits of an int; there is room to separate the two.
Did you open the files in binary mode? What are you passing to fopen?
It's one of the most "popular" C gotchas.
You should use freadand fwrite using a block at a time
FILE *fd1 = fopen("source.bmp", "r");
FILE *fd2 = fopen("destination.bmp", "w");
if(!fd1 || !fd2)
// handle open error
size_t l1;
unsigned char buffer[8192];
//Data to be read
while((l1 = fread(buffer, 1, sizeof buffer, fd1)) > 0) {
size_t l2 = fwrite(buffer, 1, l1, fd2);
if(l2 < l1) {
if(ferror(fd2))
// handle error
else
// Handle media full
}
}
fclose(fd1);
fclose(fd2);
It's substantially faster to read in bigger blocks, and fread/fwrite handle only binary data, so no problem with \n which might get transformed to \r\n in the output (on Windows and DOS) or \r (on (old) MACs)

Difference between writing compressed file

I am using zlib library to compress my files for my project. I have a compressed file content having 204 chars length. when I tried to write the files in 2 different ways I am getting different chars length as the contents in the file.
When I used ,
FILE* dest = fopen("D:\File.gz", "w"); to open the destination file
and writes using
int count = fwrite(buffer, 1, size, dest);
The final file content length becomes 205.
When I used,
FILE * dest = stdout; and
int count = fwrite(buffer, 1, size, dest);
I got the correct file size as 204.
Why I am getting 2 different behaviours? When using the first method, the file created is not able to decompress, and shows invalid zip file.

How to save results of a function into text file in C

This function print the length of words with '*' called histogram.How can I save results into text file? I tried but the program does not save the results.(no errors)
void histogram(FILE *myinput)
{
FILE *ptr;
printf("\nsaving results...\n");
ptr=fopen("results1.txt","wt");
int j, n = 1, i = 0;
size_t ln;
char arr[100][10];
while(n > 0)
{
n = fscanf(myinput, "%s",arr[i]);
i++;
}
n = i;
for(i = 0; i < n - 1; i++)
{
ln=strlen(arr[i]);
fprintf(ptr,"%s \t",arr[i]);
for(j=0;j<ln;j++)
fprintf(ptr, "*");
fprintf(ptr, "\n");
}
fclose(myinput);
fclose(ptr);
}
I see two ways to take care of this issue:
Open a file in the program and write to it.
If running with command line, change the output location for standard out
$> ./histogram > outfile.txt
Using the '>' will change where standard out will write to. The issue with '>' is that it will truncate a file and then write to the file. This means that if there was any data in that file before, it is gone. Only the new data written by the program will be there.
If you need to keep the data in the file, you can change the standard out to append the file with '>>' as in the following example:
$> ./histogram >> outfile.txt
Also, there does not have to be a space between '>' and the file name. I just do that for preference. It could look like this:
$> ./histogram >outfile.txt
If your writing to a file will be a one time thing, changing standard out is probably be best way to go. If you are going to do it every time, then add it to the code.
You will need to open another FILE. You can do this in the function or pass it in like you did the file being read from.
Use 'fprintf' to write to the file:
int fprintf(FILE *restrict stream, const char *restrict format, ...);
Your program may have these lines added to write to a file:
FILE *myoutput = fopen("output.txt", "w"); // or "a" if you want to append
fprintf(myoutput, "%s \t",arr[i]);
Answer Complete
There may be some other issues as well that I will discuss now.
Your histogram function does not have a return identifier. C will set it to 'int' automatically and then say that you do not have a return value for the function. From what you have provided, I would add the 'void' before the function name.
void histogram {
The size of arr's second set of arrays may be to small. One can assume that the file you are reading from does not exceed 10 characters per token, to include the null terminator [\0] at the end of the string. This would mean that there could be at most 9 characters in a string. Else you are going to overflow the location and potentially mess your data up.
Edit
The above was written before a change to the provided code that now includes a second file and fprintf statements.
I will point to the line that opens the out file:
ptr=fopen("results1.txt","wt");
I am wondering if you mean to put "w+" where the second character is a plus symbol. According to the man page there are six possibilities:
The argument mode points to a string beginning with one of the
following sequences (possibly followed by additional characters, as
described below):
r Open text file for reading. The stream is positioned at the
beginning of the file.
r+ Open for reading and writing. The stream is positioned at the
beginning of the file.
w Truncate file to zero length or create text file for writing.
The stream is positioned at the beginning of the file.
w+ Open for reading and writing. The file is created if it does
not exist, otherwise it is truncated. The stream is
positioned at the beginning of the file.
a Open for appending (writing at end of file). The file is
created if it does not exist. The stream is positioned at the
end of the file.
a+ Open for reading and appending (writing at end of file). The
file is created if it does not exist. The initial file
position for reading is at the beginning of the file, but
output is always appended to the end of the file.
As such, it appears you are attempting to open the file for reading and writing.

Trying not to overwrite a file in C?

Hi I'm trying not to overwrite a file in C using fopen(file, "w");
My question is the file already exists as a 10 MB file but when I used the fopen the file ends up becoming 1KB. I want to write something to the file but I want it to stay the same size as well. How would I accomplish this? I saw that the "a+" appends things to the end of the file but what if I want to write something to the beginning of the file without expanding the size? It's just an empty file
Alternatively, is there a way to create a file in C with a certain size (such as 10MB)?
Yes, it is possible. By opening it with r+ you open it for 'reading and writing' (while w opens it for writing freshly).
Regarding your other question: Open a file with w and write 1000 1024 byte blocks to the file like this:
FILE *fp = fopen("file", "wb");
if(fp) {
int i = 0;
char Buf[1024];
for(; i < 1000; ++i)
fwrite(Buf, 1, 1024, fp);
fclose(fp);
}
Just once more the fopen flags for you:
r -> Opens file for reading. (File remains unchanged)
w -> Opens file for writing. (File gets erased)
a -> Opens file for appending. (File remains unchanged, file pointer gets moved to end)
Aside from these three main types, you can add a few more additional options:
b -> Opens the file as binary, ignoring formatting characters like \n
t -> Opens the file as text, specifically parsing \n as \r\n under Windows.
Open the file, then use fseek to set your position to the beginning of your file.
Edit: use r+ mode when opening. From man fopen:
r+ Open for reading and writing. The stream is positioned at
the beginning of the file.
*a way to create a file in C with a certain size (such as 10MB)?
like this:
#include <stdio.h>
int main(void){
const char *TenMBfile = "TenMB";
FILE *fp;
fp=fopen(TenMBfile, "w");
fseek(fp, 10*1024*1024-1,SEEK_SET);
fputc(0, fp);
fclose(fp);
return 0;
}
Hye! I worked on a project for adding text or 'blog' post on my web page and I found a pretty cool way to do it.
For this, I'll use a HTML file and my program.
HTML FILE:
<html>
<body>
<p> Hey this is the asssdsadasdsadas paragraph</p><br>
<p> Hey this is the asssdsadasdsadas paragraph</p><br>
</body>
</html>
C FILE:
printf("Please enter the number of bytes to write from in %s .\n", argv[0]);
int offset;
scanf("%d", &offset);
fseek(fp, -offset, SEEK_END);
strcat(argv[1], "<br>\n\n");
fprintf(fp, "%s", argv[1]);
fprintf(fp, "</body>\n</html>\n");
HTML explanation:
I start with one line defined
I put a blank line which I am going to write there.
Then I got all my ending tags.
C explanation:
I ask how many bytes I want to seek from the ending of the file wich is 17 in this case(to write to the blank line).
I get the number with scanf()
Then I seek in the file at minus x bytes because normally it's going to add bytes and we specify the whence.
Then for the purpose, here I add a break tag and also 2 newline to continue the cycle.
Then I write my wanted text.
Last, I add my 2 last tags, because when I write my text, it overwrites all after it. So after, the cursor is positioned after the last newline and I can write the ending tags.
So... This is how you can do it.

Is there any way to create dummy file descriptor in linux?

I have opened one file with following way:
fp = fopen("some.txt","r");
Now in this file the 1st some bytes lets say 40 bytes are unnecessary junk of data so I want to remove them. But I cannot delete that data from that file, modify or
create duplicates of that file without that unnecessary data.
So I want to create another dummy FILE pointer which points to the file and when I pass this dummy pointer to any another function that does the following operation:
fseek ( dummy file pointer , 0 , SEEK_SET );
then it should set the file pointer at 40th position in my some.txt.
But the function accepts a file descriptor so i need to pass a file descriptor which will treat the file as those first 40 bytes were never in the file.
In short that dummy descriptor should treat the file as those 40 bytes were not in that file and all positioning operations should be with respect to that 40th byte counting as the is 1st byte.
Easy.
#define CHAR_8_BIT (0)
#define CHAR_16_BIT (1)
#define BIT_WIDTH (CHAR_8_BIT)
#define OFFSET (40)
FILE* fp = fopen("some.txt","r");
FILE* dummy = NULL;
#if (BIT_WIDTH == CHAR_8_BIT)
dummy = fseek (fp, OFFSET*sizeof(char), SEEK_SET);
#else
dummy = fseek (fp, OFFSET*sizeof(wchar_t), SEEK_SET);
#endif
The SEEK_SET macro indicates beginning of file, and depending on whether you are using 8-bit characters (ASCI) or 16-bit characters (eg: UNICODE) you will step 40 CHARACTERS forward from the beginning of your file pointer, and assign that pointer/address to dummy.
Good luck!
These links will likely be helpful as well:
char vs wchar_t
http://www.cplusplus.com/reference/clibrary/cstdio/fseek/
If you want, you can just convert a file descriptor to a file pointer via the fdopen() call.
http://linux.die.net/man/3/fdopen
fseek ( dummy file pointer , 0 , SEEK_SET );
In short that dummy pointer should treat the file as there is no that 40 byte in that file and all position should be with respect to that 40th byte as counting as it is 1st byte.
You have conflicting requirements, you cannot do this with the C API.
SEEK_SET always refers to the absolute position in the file, which means if you want that command to work, you have to modify the file and remove the junk.
On linux you could write a FUSE driver that would present the file like it was starting from the 40th byte, but that's a lot of work. I'm only mentioned this because it's possible to solve the problem you've created, but it would be quite silly to actually do this.
The simplest thing of course would be just to abandon this emulating layer idea you're looking for, and write code that can handle that extra header junk.
If you want to remove the first 40 bytes of a file on the disk without creating another file, then you can copy the content from the 41th byte and onwards into a buffer, then write it back at offset -40. Then use ftruncate (a POSIX library in unistd.h) to truncate at (filesize - 40) offset.
I wrote a small code with what i understood from your question.
#include<stdio.h>
void readIt(FILE *afp)
{
char mystr[100];
while ( fgets (mystr , 100 , afp) != NULL )
puts (mystr);
}
int main()
{
FILE * dfp = NULL;
FILE * fp = fopen("h4.sql","r");
if(fp != NULL)
{
fseek(fp,10,SEEK_SET);
dfp = fp;
readIt(dfp);
fclose(fp);
}
}
The readIt() is reading the file from the 11 byte.
Is this what you are expecting or something else?
I haven't actually tried this, but I think you should be able to use mmap (with the MAP_SHARED option) to get your file mapped into your address space, and then fmemopen to get a FILE* that refers to all but the first 40 bytes of that buffer.
This gives you a FILE* (as you describe in the body of your question), but I believe not a file descriptor (as in the title and elsewhere in the question). The two are not the same, and AFAIK the FILE* created with fmemopen does not have an associated file descriptor.

Resources