Chinaunix

标题: fread读取文件内容 [打印本页]

作者: WHITLACK    时间: 2008-12-23 21:38
标题: fread读取文件内容
将本地的几个文件上传到服务器上,
不知道可以用什么办法?

我想到的是用先将几个文件打包,然后fread

可是现在有个问题是,fread读取文本文件是可以的,

我用tar打包后,使用fread,上传到服务器上的文件都是0字节的空文件

不知fread函数对读取文件的格式有什么要求?
有什么方法可以解决吗?

谢谢?



 72  fp = fopen(file, "r");//如果此处file为文本文件,读取就没有问题,如果是tar包,就会上传空的文件上去

 73     if (fp == NULL) {
 74         printf("file open fail!\n");
 75         return -1;
 76     }
 77     fd = fileno(fp);
 78     fstat(fd, &theStat);
 79
 80     if (theStat.st_size > length) {
 81         printf("file is too big!\n");
 82         fclose(fp);
 83         return -1;
 84     }
 85     readCnt = fread(buf, 1, theStat.st_size, fp);
&nbsp;86     if (readCnt < theStat.st_size ){
&nbsp;87         printf("lose some.%d %d\n", readCnt,(int)theStat.st_size);
&nbsp;88         fclose(fp);
&nbsp;89         return -1;
&nbsp;90     }


[ 本帖最后由 WHITLACK 于 2008-12-24 04:35 编辑 ]
作者: tyc611    时间: 2008-12-23 22:07
最好用二进制文件"rb"方式
没看到写数据?
另外,为什么不用脚本什么的来做,方便些

[ 本帖最后由 tyc611 于 2008-12-23 22:10 编辑 ]
作者: WHITLACK    时间: 2008-12-23 22:15
原帖由 tyc611 于 2008-12-23 22:07 发表
读二进制文件"rb"试试
另外,为什么不用脚本什么的来做,方便些



谢谢回复,用脚本是方便些,但是因为这个东西的基本框架已经做好了,接口已经有了,就差往里面填内容了,所以就这样做了


我在fopen里用了rb,但是服务器那端报错,是不是因为我上面是这样定义的?

char *buf

程序运行不报错,但是服务器端提示失败
作者: tyc611    时间: 2008-12-23 23:06
标题: 回复 #3 WHITLACK 的帖子
你buf分配内存了吧?
你的代码不全,我也无法判断问题在哪
作者: WHITLACK    时间: 2008-12-23 23:40
标题: 回复 #4 tyc611 的帖子
在这里还要特意为buf分配内存吗?

我如果读取一个文本文件是正常的啊

一读tar包就会出错
作者: c/unix    时间: 2008-12-23 23:42
提示: 作者被禁止或删除 内容自动屏蔽
作者: WHITLACK    时间: 2008-12-23 23:56
代码大致是这样的,接口已经做好了,现在只需要把CONFFILES_NAME的内容交给*buf就可以了

但是由于是多个文件,所以采用了tar打包的方法(tar打包调用脚本已经省略),但是这样就会出错,

如果CONFFILES_NAME是一个文本文件,就没有问题

在此再次谢过各位!


49 int dev_getconfigfile(char *buf, int length, int *pflen)
&nbsp;50 {
&nbsp;51     int readCnt = 0;
&nbsp;52     FILE *fp;
&nbsp;53     int fd;
&nbsp;54     struct stat theStat;
&nbsp;55     char filename[128];
&nbsp;56     strcpy(filename, CONFFILES_NAME);
&nbsp;57     fp = fopen(filename, "r");
&nbsp;58     if (fp == NULL) {
&nbsp;59         printf("file open fail!\n");
&nbsp;60         return -1;
&nbsp;61     }
&nbsp;62     fd = fileno(fp);
&nbsp;63     fstat(fd, &theStat);
&nbsp;64     
&nbsp;65     if (theStat.st_size > length) {
&nbsp;66         printf("file is too big!\n");
&nbsp;67         fclose(fp);
&nbsp;68         return -1;
&nbsp;69     }   
&nbsp;70     
&nbsp;71     readCnt = fread(buf, 1, theStat.st_size, fp);
&nbsp;72     if (readCnt < theStat.st_size ){
&nbsp;73         printf("lose some.%d %d\n", readCnt,(int)theStat.st_size);
&nbsp;74         fclose(fp);
&nbsp;75         return -1;
&nbsp;76     }
&nbsp;77     fclose(fp);
&nbsp;78     *pflen = theStat.st_size;
&nbsp;79     return 0;
&nbsp;80 }


[ 本帖最后由 WHITLACK 于 2008-12-24 04:36 编辑 ]
作者: c/unix    时间: 2008-12-24 00:06
提示: 作者被禁止或删除 内容自动屏蔽
作者: ynchnluiti    时间: 2008-12-24 05:23

  1. 65     if (theStat.st_size > length) {
  2. 66         printf("file is too big!\n");
  3. 67         fclose(fp);
  4. 68         return -1;
  5. 69     }
复制代码

如果tar件大于length就退出了。所以要tar文件比较小或者length比较大,才能保证tar文件的内容一次赋值给buf,不然不会给buf赋值。

不知道buf赋值后怎么用的。如果当成字符串用的肯定不行。
Tar文件格式

  1.   struct tar_header
  2.   {
  3.    char name[100];
  4.    char mode[8];
  5.    char uid[8];
  6.    char gid[8];
  7.    char size[12];
  8.    char mtime[12];
  9.    char chksum[8];
  10.    char typeflag;
  11.    char linkname[100];
  12.    char magic[6];
  13.    char version[2];
  14.    char uname[32];
  15.    char gname[32];
  16.    char devmajor[8];
  17.    char devminor[8];
  18.    char prefix[155];
  19.    char padding[12];
  20.   };
复制代码


http://www.cublog.cn/u/12592/showart_457496.html
http://www.moon-soft.com/program/FORMAT/comm/tar.htm
作者: dragonfly0427    时间: 2008-12-24 07:11
fread  语法:
  #include <stdio.h>
  int fread( void *buffer, size_t size, size_t num, FILE *stream );

函数fread()读取[num]个对象(每个对象大小为size(大小)指定的字节数),并把它们替换到由buffer(缓冲区)指定的数组. 数据来自给出的输入流. 函数的返回值是读取的内容数量...

使用feof()或ferror()判断到底发生哪个错误.


fopen  语法:
  #include <stdio.h>
  FILE *fopen( const char *fname, const char *mode );
fopen()函数打开由fname(文件名)指定的文件, 并返回一个关联该文件的流.如果发生错误, fopen()返回NULL. mode(方式)是用于决定文件的用途(例如 用于输入,输出,等等)
作者: spiritX    时间: 2008-12-24 09:06
应该没什么问题啊.

直接用read吧.
作者: chary8088    时间: 2008-12-24 09:59
原帖由 WHITLACK 于 2008-12-23 21:38 发表
将本地的几个文件上传到服务器上,
不知道可以用什么办法?

我想到的是用先将几个文件打包,然后fread

可是现在有个问题是,fread读取文本文件是可以的,

我用tar打包后,使用fread,上传到服务器上的 ...



用fread 函数读取文本文件肯定是没问题的,
但是用你现在的代码读取tar肯定会出问题的,而且你可以试试,读取jpg,等二进制文件都会有问题,不完整的;

fp = fopen(file, "r");//如果此处file为文本文件,读取就没有问题,如果是tar包,就会上传空的文件上去


&nbsp;&nbsp;&nbsp;&nbsp;if (fp == NULL) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file open fail!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;fd = fileno(fp);
&nbsp;&nbsp;&nbsp;&nbsp;fstat(fd, &theStat);

&nbsp;&nbsp;&nbsp;&nbsp;if (theStat.st_size > length) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file is too big!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;int liSize = 0;
&nbsp;&nbsp;&nbsp;&nbsp;while(liSize < theStat.st_size)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;readCnt = fread(buf + liSize, 1, 1024, fp);
&nbsp;&nbsp;&nbsp;&nbsp;liSize += 1024;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (readCnt < theStat.st_size ){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("lose some.%d %d\n", readCnt,(int)theStat.st_size);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}


作者: chary8088    时间: 2008-12-24 10:00
原帖由 WHITLACK 于 2008-12-23 21:38 发表
将本地的几个文件上传到服务器上,
不知道可以用什么办法?

我想到的是用先将几个文件打包,然后fread

可是现在有个问题是,fread读取文本文件是可以的,

我用tar打包后,使用fread,上传到服务器上的 ...



用fread 函数读取文本文件肯定是没问题的,
但是用你现在的代码读取tar肯定会出问题的,而且你可以试试,读取jpg,等二进制文件都会有问题,不完整的;
LZ用下面我修改的代码就应该没问题的,不信可以试试!

fp = fopen(file, "r");//如果此处file为文本文件,读取就没有问题,如果是tar包,就会上传空的文件上去


&nbsp;&nbsp;&nbsp;&nbsp;if (fp == NULL) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file open fail!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;fd = fileno(fp);
&nbsp;&nbsp;&nbsp;&nbsp;fstat(fd, &theStat);

&nbsp;&nbsp;&nbsp;&nbsp;if (theStat.st_size > length) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file is too big!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;int liSize = 0;
&nbsp;&nbsp;&nbsp;&nbsp;while(liSize < theStat.st_size)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;readCnt = fread(buf + liSize, 1, 1024, fp);
&nbsp;&nbsp;&nbsp;&nbsp;liSize += 1024;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (readCnt < theStat.st_size ){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("lose some.%d %d\n", readCnt,(int)theStat.st_size);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}


作者: 雨过白鹭洲    时间: 2008-12-24 10:03
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define CONFFILES_NAME "test.tar"

int dev_getconfigfile(char *buf, int length, int *pflen)
{
&nbsp;&nbsp;&nbsp;&nbsp;int readCnt = 0;
&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp;
&nbsp;&nbsp;&nbsp;&nbsp;int fd;
&nbsp;&nbsp;&nbsp;&nbsp;struct stat theStat;
&nbsp;&nbsp;&nbsp;&nbsp;char filename[128];
&nbsp;&nbsp;&nbsp;&nbsp;strcpy(filename, CONFFILES_NAME);
&nbsp;&nbsp;&nbsp;&nbsp;fp = fopen(filename, "r");
&nbsp;&nbsp;&nbsp;&nbsp;if (fp == NULL) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file open fail!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;fd = fileno(fp);
&nbsp;&nbsp;&nbsp;&nbsp;fstat(fd, &theStat);

&nbsp;&nbsp;&nbsp;&nbsp;if (theStat.st_size > length) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file is too big!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}   

&nbsp;&nbsp;&nbsp;&nbsp;readCnt = fread(buf, 1, theStat.st_size, fp);
&nbsp;&nbsp;&nbsp;&nbsp;if (readCnt < theStat.st_size ){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("lose some.%d %d\n", readCnt,(int)theStat.st_size);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;*pflen = theStat.st_size;
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}

int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;char buf[102400];
&nbsp;&nbsp;&nbsp;&nbsp;int pflen;
&nbsp;&nbsp;&nbsp;&nbsp;int rs = dev_getconfigfile(buf, 102400, &pflen);
&nbsp;&nbsp;&nbsp;&nbsp;printf("rs = %d\n", rs);
&nbsp;&nbsp;&nbsp;&nbsp;printf("pflen = %d\n", pflen);
&nbsp;&nbsp;&nbsp;&nbsp;int i;
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < pflen; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", buf[i]);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


我用你的函数,测试了下,在我的机器上是可以正常读取出来的

不过不推荐这样使用,你直接读取文件,判断是否到文件尾不是很好吗
作者: chary8088    时间: 2008-12-24 10:04
因为fread 或者read函数读取数据时遇到'\0', 0, 文件结束符都会返回的,所以必须强制它读取到文件的结尾,特别是读取二进制文件
作者: chary8088    时间: 2008-12-24 10:07
fp = fopen(file, "r");//如果此处file为文本文件,读取就没有问题,如果是tar包,就会上传空的文件上去



&nbsp;&nbsp;&nbsp;&nbsp;if (fp == NULL) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file open fail!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;fd = fileno(fp);
&nbsp;&nbsp;&nbsp;&nbsp;fstat(fd, &theStat);

&nbsp;&nbsp;&nbsp;&nbsp;if (theStat.st_size > length) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("file is too big!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;int liSize = 0;//buf的大小必须大于1024

&nbsp;&nbsp;&nbsp;&nbsp;while(liSize < theStat.st_size)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;readCnt = fread(buf + liSize, 1, 1024, fp);
&nbsp;&nbsp;&nbsp;&nbsp;liSize += 1024;
&nbsp;&nbsp;&nbsp;&nbsp;}//这种是最安全的读取方法

&nbsp;&nbsp;&nbsp;&nbsp;if (readCnt < theStat.st_size ){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("lose some.%d %d\n", readCnt,(int)theStat.st_size);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}

作者: 雨过白鹭洲    时间: 2008-12-24 10:16
原帖由 chary8088 于 2008-12-24 10:04 发表
因为fread 或者read函数读取数据时遇到'\0', 0, 文件结束符都会返回的,所以必须强制它读取到文件的结尾,特别是读取二进制文件


遇到'\0'和0不会结束的
作者: chary8088    时间: 2008-12-24 10:35
标题: 回复 #17 雨过白鹭洲 的帖子
LS的试试就知道了!

我在gcc VC都是一样的,遇到0就会返回的;
读二进制要强制读取指定大小的
作者: ynchnluiti    时间: 2008-12-24 16:45
原帖由 chary8088 于 2008-12-24 10:35 发表
LS的试试就知道了!

我在gcc VC都是一样的,遇到0就会返回的;
读二进制要强制读取指定大小的

你是根据打印的结果判断,还是根据fread的返回值判断的。
作者: WHITLACK    时间: 2008-12-24 17:07
标题: 回复 #16 chary8088 的帖子
chary8088 兄,按照您的方法,服务器端仍然会提示上传失败

to LS各位兄弟:
      
      会不会是因为服务器端是将buf当做字符串进行处理的,因此上传失败?

      需要将buf转换为字符型吗?如果需要,应该怎么做啊?谢谢
作者: ynchnluiti    时间: 2008-12-24 17:18
原帖由 WHITLACK 于 2008-12-24 17:07 发表
chary8088 兄,按照您的方法,服务器端仍然会提示上传失败

to LS各位兄弟:
      
      会不会是因为服务器端是将buf当做字符串进行处理的,因此上传失败?

      需要将buf转换为字符型吗?如果需要 ...

应该不会吧。

你是把buf的内容直接发给服务器。
客户端:fread  -----buf---->服务器fwrite?

作者: WHITLACK    时间: 2008-12-24 19:31
标题: 回复 #21 ynchnluiti 的帖子
应该是这样的吧,本地好像没有对buf进行什么处理了
作者: 皇家救星    时间: 2008-12-24 23:16
fp = fopen(file, "r");//

换成

fp = fopen(file, "rb");//
作者: samon_fu    时间: 2008-12-24 23:34
标题: 回复 #1 WHITLACK 的帖子
fread函数中的参数里有一个参数,设置后可以二进制读写文件。即可解决问题。
作者: WHITLACK    时间: 2008-12-25 00:26
谢谢LS两位兄弟回复,用了fp = fopen(file,"rb")还是不行,程序不报错,但是服务器端提示上传失败
作者: fiyiyi2000    时间: 2009-03-05 09:03
我觉得应该是你服务器代码处理的问题
你发送过去的buffer,在服务器上写入的时候要调用frwite写入,并且还要知道长度
作者: chary8088    时间: 2009-03-05 12:05
我的那种方法肯定可以的,我的程序就是那样处理的,呵呵
LZ不信可以看下能否发送RAR和二进制的文件??!

http://www.google.cn/search?clie ... 1%E4%B8%93%E5%AE%B6
作者: 皇家救星    时间: 2009-03-05 12:57
1 buff是否有分配足够空间
2 buff是以什么样的形式传上服务器的
3 服务是怎么接收的
4 服务器是怎么写文件的

这四个步骤都要配合好,全以二进制形式处理才行




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2