简体   繁体   English

c将read()和write()内容编程到文件中

[英]c programming read() and write() content to file

The user should input some file names in the command line and the program will read each file name from argv[] array. 用户应在命令行中输入一些文件名,程序将从argv[]数组中读取每个文件名。 I have to perform error checking etc. 我必须执行错误检查等。

I want to read each filename. 我想阅读每个文件名。 For example, if argv[2] is 'myfile.txt', the program should read the content of 'myfile.txt' and store value in char buffer[BUFSIZ] and then write the content of buffer into another file. 例如,如果argv [2]是“ myfile.txt”,则程序应读取“ myfile.txt”的内容,并将值存储在char buffer[BUFSIZ] ,然后将buffer的内容写入另一个文件。

However before the content is written, the program should also write the name of the file and the size. 但是在编写内容之前,程序还应该写入文件名和大小。 Such that the file can be easily extracted later. 这样以后就可以轻松提取文件了。 A bit like the tar function. 有点像tar函数。

The file I write the content of buffer , depending on the number of files added by user, should be a string like: 我写buffer内容的文件,取决于用户添加的文件数,应该是一个字符串,如:

myfile.txt256Thisisfilecontentmyfile2.txt156Thisisfile2content..............

My question is 我的问题是

1) How do I write value of argv[2] into file using write() statement, as having problems writing char array, what should I put as (sizeof(?)) inside write() . 1)我如何使用write()语句将argv[2]write()文件,因为在写入char数组时遇到问题,我应该在write()中将(sizeof(?))放在什么位置。 see below as I don't know the length of the file name entered by the user. 请参阅下文,因为我不知道用户输入的文件名的长度。

2) Do I use the '&' to write an integer value into file after name, for example write 4 bytes after file name for the size of file 2)我是否使用'&'在名称后将整数值写入文件,例如在文件名后写入4个字节作为文件大小

Here is the code I have written, 这是我写的代码,

char buffer[BUFSIZ];
int numfiles=5; //say this is no of files user entered at command
open(file.....

lseek(fdout, 0, SEEK_SET); //start begging of file and move along each file some for loop

for(i=0-; ......
//for each file write filename,filesize,data....filename,filesize,data......
int bytesread=read(argv[i],buffer,sizeof(buffer));
write(outputfile, argv[i], sizeof(argv)); //write filename size of enough to store value of filename
write(outputfile, &bytesread, sizeof(bytesread));
write(outputfile, buffer, sizeof(buffer));

But the code is not working as I expected. 但是代码无法正常工作。

Any suggestions? 有什么建议么?

Since argv consists of null-terminated arrays, the length you can write is strlen(argv[2])+1 to write both the argument and null terminator: 由于argv由以null结尾的数组组成,因此可以编写的长度是strlen(argv[2])+1来写入参数和null终止符:

size_t sz = strlen (argv[2]);
write (fd, argv[2], sz + 1);

Alternatively, if you want the length followed by the characters, you can write the size_t itself returned from strlen followed by that many characters. 或者,如果您希望长度后跟字符,您可以编写从strlen返回的size_t本身,后跟那么多字符。

size_t sz = strlen (argv[2]);
write (fd, &sz, sizeof (size_t));
write (fd, argv[2], sz);

You probably also need to write the length of the file as well so that you can locate the next file when reading it back. 您可能还需要编写文件的长度,以便在读取时可以找到下一个文件。

1., You can write the string the following way: 1.,您可以通过以下方式编写字符串:

size_t size = strlen(string);
write(fd, string, size);

However, most of the time it's not this simple: you will need the size of the string so you'll know how much you need to read. 但是,在大多数情况下,事情并不是那么简单:您将需要字符串的大小,以便知道需要阅读多少内容。 So you should write the string size too. 所以你也应该写字符串大小。

2., An integer can be written the following way: 2.,可以通过以下方式写整数:

write(fd, &integer, sizeof(integer));

This is simple, but if you plan to use the file on different architectures, you'll need to deal with endianness too. 这很简单,但是如果您打算在不同的体系结构上使用该文件,则也需要处理字节序。

It sounds like your best bet is to use a binary format. 听起来最好的选择是使用二进制格式。 In your example, is the file called myfile.txt with a content length of 256, or myfile.txt2 with a content length of 56, or myfile.txt25 with a content length of 6? 在您的示例中,文件名为myfile.txt ,内容长度为256,或myfile.txt2 ,内容长度为56,或myfile.txt25 ,内容长度为6? There's no way to distinguish between the end of the filename and the start of the content length field. 无法区分文件名的结尾和内容长度字段的开头。 Similarly there is no way to distinguish between the end of the content length and the start of the content. 类似地,没有办法区分内容长度的结尾和内容的开头。 If you must use a text format, fixed width fields will help with this. 如果必须使用文本格式,固定宽度字段将有助于此。 Ie 32 characters of filename followed by 6 digits of content length. 即32个字符的文件名后跟6个内容长度的数字。 But binary format is more efficient. 但是二进制格式更有效。

You get the filename length using strlen(), don't use sizeof(argv) as you will get completely the wrong result. 您使用strlen()获得文件名长度,而不要使用sizeof(argv)因为您将得到完全错误的结果。 sizeof(argv[i]) will also give the wrong result. sizeof(argv[i])也会给出错误的结果。

So write 4 bytes of filename length followed by the filename then 4 bytes of content length followed by the content. 因此,先写入4个字节的文件名长度,然后写入文件名,然后写入4个字节的内容长度,然后写入内容。

If you want the format to be portable you need to be aware of byte order issues. 如果您希望格式具有可移植性,则需要注意字节顺序问题。

Lastly, if the file won't all fit in your buffer then you are stuffed. 最后,如果文件不能全部放入缓冲区中,那么您就被塞满了。 You need to get the size of the file you are reading to write it to your output file first, and then make sure you read that number of bytes from the first file into the second file. 您需要先获取正在读取的文件的大小,然后将其写入输出文件,然后确保从第一个文件读取该字节数到第二个文件。 There are various techniques to do this. 有多种技术可以做到这一点。

thanks for replies guys, 谢谢你们的回复,

I decided not to use (size_t) structure instead just assigned (int) and (char) types so I know exact value of bytes to read() out. 我决定不使用(size_t)结构而只是分配(int)和(char)类型,所以我知道read()out的字节的确切值。 ie I know start at beggining of file and read 4 bytes(int) to get value of lenght of filename, which I use as size in next read() 即我知道从文件的开始读取并读取4个字节(int)以获取文件名长度的值,我将其用作下一个read()中的大小

So, when I am writing (copying file exactly with same name) users inputted file to the output file (copied file) I writing it in long string, without spaces obviously just to make it readable here, 所以,当我正在写(用同名复制文件)用户输入文件到输出文件(复制文件)我用长字符串写,没有空格显然只是为了使它在这里可读,

filenamesize filename filecontentsize filecontent ie 10 myfile.txt 5 hello filenamesize filename filenamefilecontentsize filecontent即10 myfile.txt 5你好

So when come to reading that data out I start at begining of file using lseek() and I know the first 4 bytes are (int) which is lenght of filename so I put that into value int namelen using the read function. 因此,当读取数据时,我开始使用lseek()开始文件,我知道前4个字节是(int),这是文件名的长度所以我使用read函数将其放入值int namelen。

My problem is I want to use that value read for the filenamesize(first 4 bytes) to declare my array to store filename with the right lenght. 我的问题是我想使用为filenamesize(前4个字节)读取的值来声明我的数组以正确的长度存储文件名。 How do I put this array into read() so the read stores value inside that char array specified, see below please 我如何将这个数组放入read()中,以便read将值存储在指定的char数组内,请参见下文

int namelen; //value read from first 4 bytes of file lenght of filename to go in nxt read()
char filename[namelen]; 
read(fd, filename[namelen], namelen);//filename should have 'myfile.txt' if user entered that filename

So my question is once I read that first 4 bytes from file giving me lenght of filename stored in namelen, I then want to read namelen amount of bytes to give me the filename of originally file so I can create copied file inside directory? 所以我的问题是,一旦我从文件中读取前4个字节给我长度存储在namelen中的文件名,然后我想读取namelen字节数给我原始文件的文件名,这样我就可以在目录中创建复制文件了?

Thanks 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM