【问题标题】:c programming read() and write() content to filec 将 read() 和 write() 内容编程到文件中
【发布时间】:2011-05-23 10:12:50
【问题描述】:

用户应该在命令行中输入一些文件名,程序将从argv[]数组中读取每个文件名。我必须执行错误检查等。

我想读取每个文件名。例如,如果 argv[2] 是 'myfile.txt',程序应该读取 'myfile.txt' 的内容并将值存储在char buffer[BUFSIZ] 中,然后将buffer 的内容写入另一个文件。

但是在写入内容之前,程序还应该写入文件名和大小。这样以后可以轻松提取文件。有点像tar 函数。

我写buffer内容的文件,根据用户添加的文件数量,应该是这样的字符串:

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

我的问题是

1) 如何使用write() 语句将argv[2] 的值写入文件,因为在写入char 数组时遇到问题,我应该在@987654329 中放入什么(sizeof(?)) @。见下文,因为我不知道用户输入的文件名的长度。

2)我是否使用'&'将整数值写入文件名后,例如在文件名后写入4个字节作为文件大小

这是我写的代码,

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));

但是代码没有像我预期的那样工作。

有什么建议吗?

【问题讨论】:

  • 如果是作业,请更新标签。
  • 你为什么使用 open() 而不是 fopen() 和 write() 而不是 fwrite()?

标签: c


【解决方案1】:

谢谢大家的回复,

我决定不使用 (size_t) 结构,而是只分配 (int) 和 (char) 类型,因此我知道要读取 () 的字节的确切值。即我知道从文件开始并读取 4 个字节(int)以获取文件名的长度值,我在下一次读取()中将其用作大小

所以,当我写(复制文件完全相同的名称)用户输入文件到输出文件(复制文件)时,我用长字符串写它,显然没有空格只是为了让它在这里可读,

文件名大小文件名文件内容大小文件内容 即 10 myfile.txt 5 你好

因此,当我开始读取该数据时,我使用 lseek() 从文件开头开始,我知道前 4 个字节是 (int),它是文件名的长度,所以我使用 read 函数将其放入 value int namelen 中。

我的问题是我想使用读取的文件名大小(前 4 个字节)的值来声明我的数组以存储具有正确长度的文件名。如何将此数组放入 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

所以我的问题是,一旦我从文件中读取了前 4 个字节,给了我存储在 namelen 中的文件名长度,然后我想读取 namelen 字节数来给我原始文件的文件名,这样我就可以在目录中创建复制的文件?

谢谢

【讨论】:

    【解决方案2】:

    听起来你最好的选择是使用二进制格式。在您的示例中,名为 myfile.txt 的文件是内容长度为 256 的文件,还是名为 myfile.txt2 的内容长度为 56 的文件,还是名为 myfile.txt25 的内容长度为 6 的文件?无法区分文件名的结尾和内容长度字段的开头。同样,没有办法区分内容长度的结尾和内容的开头。如果您必须使用文本格式,固定宽度字段将对此有所帮助。 IE。 32 个字符的文件名,后跟 6 位内容长度。但二进制格式更高效。

    您使用 strlen() 获取文件名长度,不要使用 sizeof(argv),因为您将得到完全错误的结果。 sizeof(argv[i]) 也会给出错误的结果。

    所以写 4 个字节的文件名长度,然后是文件名,然后是 4 个字节的内容长度,然后是内容。

    如果您希望格式可移植,则需要注意字节顺序问题。

    最后,如果文件不能全部放入您的缓冲区,那么您就被塞满了。您需要先获取正在读取的文件的大小以将其写入输出文件,然后确保将第一个文件中的字节数读入第二个文件。有多种技术可以做到这一点。

    【讨论】:

      【解决方案3】:

      1.,你可以这样写字符串:

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

      但是,大多数情况下并不是这么简单:您将需要字符串的大小,以便知道需要阅读多少内容。所以你也应该写字符串大小。

      2.,整数可以写成如下方式:

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

      这很简单,但是如果您打算在不同的架构上使用该文件,您还需要处理字节序。

      【讨论】:

        【解决方案4】:

        由于argv 由以null 结尾的数组组成,因此您可以编写的长度为strlen(argv[2])+1 以同时写入参数和null 终止符:

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

        或者,如果您想要长度后跟字符,您可以编写从strlen 返回的size_t 本身,后跟那么多字符。

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

        您可能还需要写入文件的长度,以便在读取时可以找到下一个文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-02-15
          • 1970-01-01
          • 1970-01-01
          • 2022-12-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多