所以我现在正在程序的服务器端工作,我想执行以下操作:
1)以读写模式打开文件
2)在文件末尾附加一个单词(WORD)
3)[我相信我已经把所有这部分都准备好了]打开管道,创建一个子进程,让它直接从文件(文件描述符)中读取,执行命令,并将结果发送到write /管道的输出。父进程从管道的读取/输入中读取信息,并将信息放入缓冲区以发送回客户端。
我遇到麻烦的是附加部分。我非常确定它会追加到文件中(在现有文本和WORD之间插入换行符),因为当我直接打开文本文件时,它就在那里。但是,当我尝试从缓冲区中打印它时,它不存在。我尝试在写入并重新打开后关闭文件描述符,但它不存在。我试过strcat而不是写文件描述符,它不存在。
#define WORD "WORD"
#define BUFFERLENGTH 512
char buffer[BUFFERLENGTH];
int fileDesc = open (filePath, O_RDWR|O_APPEND, 0660);
if (fileDesc <= 0){
write(clientDesc, ERRORMSG, BUFFERLENGTH);
exit(EXIT_FAILURE);
}
read(fileDesc,buffer,BUFFERLENGTH);
long length = lseek(fileDesc,0,SEEK_END);
int status = write(fileDesc,WORD,sizeof(WORD)-1);
read(fileDesc, buffer, BUFFER_LEN+1);
printf("new text: %s\n", buffer); //WORD does not show up at the end of file as intended
我真的有误会吗?
也许我不完全了解open(),read(),write()和lseek()的工作原理,但是如果有人可以帮助我向我解释为什么这没有按预期进行,那将是非常重要的赞赏。在过去的一周里,我一直在为此苦苦挣扎,而我目前为寻找解决方案而打开的选项卡数量非常可悲。
答案 0 :(得分:2)
在write()
通话之后,您将位于文件末尾,因此read()
将无法读取任何内容。如果您希望能够从文件中读取任何内容,则需要lseek()
到文件中的较早位置。
您应该检查read()
的返回值(以及与此相关的几乎所有其他系统调用),并在出现错误的情况下使用perror()
或类似的方法,这将对帮助您有所帮助了解当您看到意想不到的行为时发生了什么。
修改程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define WORD "WORD"
#define BUFFERLENGTH 512
int main(void)
{
char * filePath = "testfile.txt";
char buffer[BUFFERLENGTH] = {0};
// Open file.
int fd = open(filePath, O_RDWR | O_APPEND, 0660);
if (fd < 0) {
perror("couldn't open file");
return EXIT_FAILURE;
}
// Write word to end.
int status = write(fd, WORD, strlen(WORD));
if ( status < 0 ) {
perror("couldn't write");
return EXIT_FAILURE;
}
// Seek to start of file.
long length = lseek(fd, 0, SEEK_SET);
if ( length < 0 ) {
perror("couldn't lseek");
return EXIT_FAILURE;
}
// Read contents of file.
status = read(fd, buffer, BUFFERLENGTH - 1);
if ( status < 0 ) {
perror("couldn't read");
return EXIT_FAILURE;
}
// Print buffer.
printf("file contents: %s\n", buffer);
return 0;
}
产量:
paul@mac:scratch$ touch testfile.txt
paul@mac:scratch$ ./file
file contents: WORD
paul@mac:scratch$ ./file
file contents: WORDWORD
paul@mac:scratch$ ./file
file contents: WORDWORDWORD
paul@mac:scratch$ ./file
file contents: WORDWORDWORDWORD
paul@mac:scratch$
如果您只想实际查看新内容,则需要lseek()
到文件开头以外的某个位置。由于成功的write()
将返回写入的字节数,因此您可以使用此值从文件末尾向后偏移:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define BUFFERLENGTH 512
int main(int argc, char * argv[])
{
if ( argc < 2 ) {
fprintf(stderr, "you need to enter a word argument\n");
return EXIT_FAILURE;
}
char * filePath = "testfile.txt";
char buffer[BUFFERLENGTH] = {0};
// Open file.
int fd = open(filePath, O_RDWR | O_APPEND, 0660);
if ( fd < 0 ) {
perror("couldn't open file");
return EXIT_FAILURE;
}
// Write word to end.
int status = write(fd, argv[1], strlen(argv[1]));
if ( status < 0 ) {
perror("couldn't write");
return EXIT_FAILURE;
}
// Seek to point before last write.
long length = lseek(fd, -status, SEEK_END);
if ( length < 0 ) {
perror("couldn't lseek");
return EXIT_FAILURE;
}
// Read from there to end of file.
status = read(fd, buffer, BUFFERLENGTH - 1);
if ( status < 0 ) {
perror("couldn't read");
return EXIT_FAILURE;
}
// Print buffer.
printf("new text: %s\n", buffer);
return 0;
}
收益:
paul@mac:scratch$ rm testfile.txt
paul@mac:scratch$ touch testfile.txt
paul@mac:scratch$ ./file2 these
new text: these
paul@mac:scratch$ ./file2 are
new text: are
paul@mac:scratch$ ./file2 some
new text: some
paul@mac:scratch$ ./file2 words
new text: words
paul@mac:scratch$ cat testfile.txt
thesearesomewordspaul@mac:scratch$