If I have piece of code that writes out text like this: write(1, buf, bytes); why doesn't the same works for writing to a file fwrite(1, buf, bytes,f1);?
Where f1 is declared as FILE *f1; and f1=fopen("Test.txt", "wb");. The tutorials I'm looking at indicate that it should work. I'm C# coder and not a C coder and would like some help with this.
The signature of fwrite is:
fwrite(const void * ptr, size_t size, size_t count, FILE * stream );
While the signature of write is:
write(int fd, const void *buf, size_t count);
If you match your examples you'll see that parameter don't match.
count of write should be size*count of fwrite (which let you specify the size of every element you are writing). In addition write has a file descriptor hardcoded as 1 and which you replace with a FILE* obtained from fopen, how do you know that 1 is referring to that file?
Related
Simple question,
When i use fread:
fread(ArrayA, sizeof(Reg), sizeBlock, fp);
My file pointer, fp is moved ahead?
Answer: Yes, the position of the file pointer is updated automatically after the read operation, so that successive fread() functions read successive file records.
Clarification: fread() is a block oriented function. The standard prototype is:
size_t fread(void *ptr,
size_t size,
size_t limit,
FILE *stream);
The function reads from the stream pointed to by stream and places the bytes read into the array pointed to by ptr, It will stop reading when any of the following conditions are true:
It has read limit elements of size size, or
It reaches the end of file, or
A read error occurs.
fread() gives you as much control as fgetc(), and has the advantage of being able to read more than one character in a single I/O operation. In fact, memory permitting, you can read the entire file into an array and do all of your processing in memory. This has significant performance advantages.
fread() is often used to read fixed-length data records directly into structs, but you can use it to read any file. It's my personal choice for reading most disk files.
Yes, calling fread does indeed move the file pointer. The file pointer will be advanced by the number of bytes actually read. In case of an error in fread, the file position after calling fread is unspecified.
Yes, The fp will be advanced by the total amount of bytes read.
In your case the function fread reads sizeBlock objects, each sizeof(Reg) bytes long, from the stream pointed to by fp, storing them at the location given by ArrayA.
Yes, it does. It could be checked by using ftell() function in order to show current position (in fact, bytes read so far), take a look it:
int main() {
typedef struct person {
char *nome; int age;
} person;
// write struct to file 2x or more...
FILE *file = fopen(filename, "rb");
person p;
size_t byteslength = sizeof(struct person);
printf("ftell: %ld\n", ftell(file));
fread(&p, byteslength, 1, file);
printf("name: %s | age: %d\n", p.nome, p.idade);
printf("ftell: %ld\n", ftell(file));
fread(&p, byteslength, 1, file);
printf("name: %s | age: %d\n", p.nome, p.idade);
//...
fclose(file);
return 0;
}
i've got a Textfile of Unknown Size and have to send it via Sockets from my Server to the Client in Chunks of a certain (variable Size).
How can i use Fread for that Task? I read alot about Fread but im Struggeling with the kind of Pointer i should pass that function in my Case?
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
How can i use fread for that task?
Simply keep sending chunks (of fixed size) from the Server to the Client, until there is nothing else to be sent by the Serve.
What kind of pointer I should pass that function in my case?
Anything.
Check fread()'s example, where the buffer that is passed in fread() is of type char, and fread() simply allows for it, since the first argument of that function is:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
So just pass the array you are using to store the data (the chunks) to the function.
To read file as chunks and send them to socket you'll have to decide a size of the chunk.
For example: 4096 is perfect size that's not too big or not too small!
Example
We choose 4096 bytes as the chunk size. It's btw customizable.
Send the chunk data to the Client when received from file.
#include <stdio.h>
int main(ssize_t argc, char** argv)
{
// We're going to use "rb" because in (WINDOWS) you need it!
FILE* fp = fopen(argv[1], "rb");
char byte_buffer[4096];
size_t bytes_read = 0;
while(( bytes_read = fread(&byte_buffer, 4096, 1, fp) )> 0)
send_data_chunk_to_client_somehow(/* your parameters here */);
}
The text file should be read in chunks and send them to the Client.
fread(3) ― Binary stream I/O
fread(3) is compatible with both text and binary streams, it's a part of ANSI C. The POSIX read(3) is a equivalent to the function and faster than it.
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp);
I'm writing a little library and struggling with the naming conventions. There is a structure called gk_Stream defined as follows:
typedef struct gk_Stream {
gk_Stream_writeProc write;
gk_Stream_readProc read;
void* data; // Pointer to data needed by read and write procedures.
} gk_Stream;
Now, I want to supply 2 built-in uses for this structure.
Reading/Writing from/to a FILE*
Reading/Writing from/to a buffer
I first called the functions like the following:
gk_Stream_initWithFile(gk_Stream* stream, FILE* fl);
gk_Stream_initWithBufferSize(gk_Stream* stream, size_t bufferSize);
gk_Stream_initWithStringAndBufferSize(gk_Stream* stream, char* string, size_t string_length, size_t buffer_size);
gk_Stream_deallocBuffer(gk_Stream* stream);
But another possibility would be to call them like this:
gk_Stream_file_init(/* */);
gk_Stream_buffered_initWithSize(/* */);
gk_Stream_buffered_initWithStringAndSize(/* */);
gk_Stream_buffered_dealloc(/* */);
What names do you think make most sense or look/sound best? What are the names you would want to work with when using the library?
How about:
gk_Stream_file_init(gk_Stream* stream, FILE* fl);
gk_Stream_file_deinit(gk_Stream* stream); /* not sure if necessary */
gk_Stream_buffer_init(gk_Stream* stream, size_t bufferSize);
gk_Stream_buffer_initWithString(gk_Stream* stream, char* string, size_t string_length, size_t buffer_size);
gk_Stream_buffer_deinit(gk_Stream* stream);
When I hear or read "buffered", I think of that as the method used internally to improve performance when writing to/reading from things such as files or pipes. However, that's not what's going on here. Your code can either do I/O with a file or with a buffer, so it makes sense for the function names to differentiate between performing operations on a file vs a buffer, not file and buffered.
Edit: Oh, I forgot to explain one other thing; I also would prefer deinit to dealloc, as deinit is the natural companion to init. Deallocating is perhaps how you are deinitializing the stream, but all the user of your library needs to know is that they are deinitializing the stream.
I would do this:
gk_Stream_InitWithFile(gk_Stream* stream, FILE* fl);
gk_Stream_Deinit(gk_Stream* stream);
gk_Stream_InitWithBufferSize(gk_Stream* stream, size_t buffer_size);
gk_Stream_InitWithStringAndBufferSize(gk_Stream* stream, char* string, size_t string_length, size_t buffer_size);
underscores to separate "namespaces", CamelCase for function names. lower_case for variables.
There's no standard/recommended naming conventions in C.
Use whatever you feel is best for code readability, consistent with the naming conventions followed in rest of the code/project.
It somewhat depends upon the purpose of the string argument in the buffered case.
I'd probably go with something like:
gk_Stream_file_init(gk_Stream *stream, FILE *f);
gk_Stream_mem_init(gk_Stream *stream, size_t buff_sz, const char *initval, size_t initval_sz);
gk_Stream_mem_free(tk_Stream *stream);
And then allow a NULL initval.
I am a bit puzzled over how to send a file from an http server to a client(web-browser).
First I send the header and my next task is to send the file content. However I want to send it in segments of say 512 bytes instead of the whole file at once as I ran into some problems.
I am a bit lost on how to achieve that. Here is what I want
read file1;
while (seg=get_next_segment(file1)){
do
send(seg)
until (seg_is_sent)
}
However I can't seem to find the appropriate functions to achieve that. fread and fseek crossed through my mind but the first one reads the whole file at once and with fseek I don't see a way to just grab a portion from a file(instead of reading from the file pointer until the end of the file).
freaddoes not read a whole file to the end. It reads exactly how much you tell it to read.
size_t
fread(void *restrict ptr, size_t size, size_t nitems,
FILE *restrict stream);
size_t
fwrite(const void *restrict ptr, size_t size, size_t nitems,
FILE *restrict stream);
Both functions take a size and nitems. You could set the size to 512, and the number of items to 1 (or vice versa) and read just that portion of the file.
From the man page:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.
As you can see, you don't have to read the whole file with fread, you can read it in nmemb size chunks.
If you are writing your own web-server in C, you may want to have a look at libmicrohttpd, which is a web-server in C for embedding into other applications, it can handle streaming a file for you.
I'm feeling kind... How about something like this:
for (;;)
{
char buffer[512];
size_t nread = fread(buffer, sizeof(char), 512, fp);
if (nread > 0)
send_to_socket(buffer, nread);
if (nread < 512)
{
if (feof(fp))
printf("End of file\n");
if (ferror(fp))
printf("Error reading\n");
break;
}
}
C# has a neat feature of being able to write to a memory stream using the MemoryStream object.
I'm looking for similar functionality from C using a FILE* pointer.
I want to be able to sprintf() but with the added functionality of having C remember "where I was" in the buffer I'm writing to.
If you are using the GNU C Library, you can use fmemopen(). There may be other non-portable extensions for other environments, but there's no portable way using FILE*s.
You could also, however, wrap snprintf, if you don't insist on actually using FILE*s. For example, glib (note: not the same as the GNU C Library, and portable) has a g_string_append_printf that does what you want.
There's also an ugly hack which works with plain ISO-C: You can use fopen() to open a null file (/dev/null on *nix, NUL on Windows) and set the array as the file's buffer via
setvbuf(file, buffer, _IOFBF, buffer_size)
This should work fine as long as fflush() isn't called anywhere in the code. Also, the programmer has to explicitly take care of the string delimiter.
I don't really see a need to do this, though: As snprintf() returns the number of characters written, it's trivial to keep track of a buffer's position.
One can even write a function to automagically resize the buffer on overflow: bufprintf.c
The function's prototype is
int bufprintf(char **buffer, size_t *size, size_t *offset,
const char *format, ...);
An example program could look like this:
#include <stdio.h>
extern int bufprintf(char **buffer, size_t *size, size_t *offset,
const char *format, ...);
int main(void)
{
size_t size = 0; // must be set!
size_t offset;
char * buffer;
for(int i = 0; i < 100; ++i)
bufprintf(&buffer, &size, &offset, "we rock %i\n", i);
puts(buffer);
printf("size:\t%u\noffset:\t%u\n", (unsigned)size, (unsigned)offset);
}
sprintf returns the number of characters that were printed into the string. You can use that value to increment the pointer of your buffer.
buffer += sprintf(buffer, "%d", i);
Make sure that you keep around a copy of the original pointer, as that is what you will be using when passing the buffer somewhere else.
Why not use mmap? You can map a file to memory and use a FILE* pointer.
Update: It does not work. Sorry.
MemoryStream is not a feature of C#, the language. It's simply a class in the BCL. You could write it yourself in C#.
And so it is in C - you'd write some functions that work similarly in use to fopen, fprintf, fwrite, fclose, etc., but give them names like mopen, mwrite, etc. (presumably) and write them so they operate on a memory buffer.
How about just manually managing your pointers. I don't have a compiler in front me but hopefully the code below gets the idea across:
char huge_buffer[REALLY_BIG_SIZE];
char *write_pos = huge_buffer;
//...
void fprintf_to_mem(char **mem_ptr, const char *fmt, ...)
{
va_list args;
int num_written;
va_start(args, mem_ptr);
num_written = vsprintf(*write_pos, fmt, args);
*write_pos += num_written;
va_end(args);
}
//...
fprintf_to_mem(&write_pos, "Testing %d %d %d", 1, 2, 3);
fprintf_to_mem(&write_pos, "Hello world!\r\n");
I would expect that to output "Testing 1 2 3Hello world!\r\n" to huge_buffer.