Window操作系统:文件操作编程

简介: 有些时候,我们在传输大量的数据时,为了方便比较,最简单的可以做回环测试,我们是知道自己发出去什么数据的,收发的数据完全可以分别存入文件通过cmp来比较是否正确

有些时候,我们在传输大量的数据时,为了方便比较,最简单的可以做回环测试,我们是知道自己发出去什么数据的,收发的数据完全可以分别存入文件通过cmp来比较是否正确

 Windows操作系统中,介绍一种创建数据文件的方法,主要用到三个函数(fopen和fopen_s视作一个):

1.fopen函数

函数名 :  fwrite
头文件 : <stdio.h>
功   能: 使用给定的模式mode打开filename所指向的文件
函数原型: FILE *fopen( const char *filename, const char *mode );
参   数: 参数mode字符串包含了文件访问模式,欲打开的文件路径及文件名,参数 mode 字符串则代表着流形态。mode 有下列几种形态字符串由下图说明:
返回值 :  文件顺利打开后,指向该流的文件指针就会被返回。
          如果文件打开失败则返回 NULL,并把错误代码存在error中。
          一般而言,打开文件后会做一些文件读取或写入的动作,
          若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在 fopen() 后作错误判断及处理。

9e6f2de8a7104ac199eea116b0ab5900.png

补充1:

 以 x 结尾的模式为独占模式,文件已存在或者无法创建(一般是路径不正确)都会导致 fopen 失败。文件以操作系统支持的独占模式打开。

 上述的形态字符串都可以再加一个 b 字符,如 rb、w+b 或 ab+ 等组合,加入 b 字符用来告诉函数库以二进制模式打开文件。如果不加 b,表示默认加了 t,即 rt、wt,其中 t 表示以文本模式打开文件。由 fopen() 所建立的新文件会具有 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666) 权限,此文件权限也会参考umask值。

 有些 C编译系统可能不完全提供所有这些功能,有的C版本不用"r+"、“w+”、“a+”,而用"rw"、“wr”、“ar"等,应该注意所用系统的规定。

补充2:

 二进制和文本模式的区别

 1、在Windows系统中,文本模式下,文件以”\r\n"代表换行。若以文本模式打开文件,并用 fputs 等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n"。

 2、在类 Unix/Linux 系统中文本模式下,文件以"\n"代表换行。所以 Linux 系统中在文本模式和二进制模式下并无区别。 [1]

补充3:

打开方式总结:

 各种打开方式主要有三个方面的区别:

 1、打开是否为二进制文件,用“b”标识。

 2、读写的方式,有以下几种:只读、只写、读写、追加只写、追加读写这几种方式。

 3、对文件是否必 须存在、以及存在时是清空还是追加会有不同的响应。具体判断如图所示

9158d4d7002944f9aed4f52e99b38820.png

fopen_s函数

fopen_s(&pFile,const char *filename,const char *mode );

 VS中、warning C4996: “fopen”被声明为否决的,这是微软的警告,主要是那些都是C库的函数,很多函数内部是不进行参数检测的(包括越界类的),微软担心使用这些会造成内存异常,就改写了一下同样功能的函数,进行了参数的检测。

 返回值:成功则返回0,失败会返回

7f1a23478f3a65c054036d08b7d60cf.png

错误条件

e7b57b2b871a47ae862d00062f9fc842.png

EINVAL:无效的参数。

2.fwrite函数

函数名 :  fwrite
头文件 : <stdio.h>
功   能:  写内容到流中,从指针ptr开始把n个数据项添加到给定输出流stream,每个数据项的长度为size个字节。
函数原型:  size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)    
参 数:     void *ptr      要写入的内容, 是一个指针,对fwrite来说,是要获取数据的地址
           int size       这是要被写入的每个元素的大小,以字节为单位
           int nitems     这是元素的个数,每个元素的大小为 size 字节 
           FILE *stream   这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。目标文件指针
返回值 :  如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误
用法说明: 写入到文件的哪里与文件的打开模式有关,
         如果是w+,则是从file pointer指向的地址开始写,替换掉之后的内容,文件的长度可以不变,stream的位置移动count个数;
         如果是a+,则从文件的末尾开始添加,文件长度加大。
         fseek对此函数有作用,但是fwrite函数写到用户空间缓冲区,并未同步到文件中,所以修改后要将内存与文件同步可以用fflush(FILE *fp)函数同步。

3.fclose函数

函数名 : fclose
头文件 :<stdio.h>
功   能:     1. 将输出缓冲区内容写到存储设备上 
            2. 如果不调用fclose,相应地,可能会造成对文件的更改没有被记录到磁盘上,其他进程无法存取
函数原型:int fclose(FILE *stream)
参数:
         stream-- 这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流。
返回值:  如果流成功关闭,则该方法返回零。如果失败,则返回 EOF。

示例

 数据量大的时候,为了保证数据连续常造累加数,但单字节累加是00-ff循环的,一旦整包丢掉,根本无法发现,所以可以8字节累加,以此为例在Windows下创建一个数据文件,入参为创建文件大小,单位为MB(1024*1024)


#include <iostream>
#include <fstream>
#include "conio.h"
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <strsafe.h>
#include <Windows.h>
#include <SetupAPI.h>
#include <INITGUID.H>
#include <WinIoCtl.h>
#include <string>
#include <thread>
#include <vector>
#include <Windows.h>
#include <SetupAPI.h>
#include <signal.h>
#include <INITGUID.H>
#include<process.h>
#define K_B 1024
#define M_B (K_B * K_B)
#define BLK_SIZE (128 * K_B)
FILE* file_handle;
size_t write_result = 0;
int main(int argc,char **argv)
{
    unsigned long long i,cnt;
    unsigned long long* compareptr, ptrcnt = 0;
    unsigned long long int total_size = 1000 * M_B;
    unsigned char *buffer;
    buffer = (unsigned char*)malloc(BLK_SIZE + K_B);
    if (argc < 2)
        printf("usage: %s x_MB\r\n",argv[0]);
    if (argv[1])
        total_size = ((unsigned long long)atoi(argv[1])) * M_B;
    if (fopen_s(&file_handle, "file_test.bin", "w+b") != 0)
    {
        file_handle = NULL;
        printf("fopen_s failed,errno  = %d\r\n",GetLastError());
        return -1;
    }
    printf("total_size =%llu,total_size / BLK_SIZE = %d\r\n", total_size, total_size / BLK_SIZE);
    for (cnt = 0; cnt < total_size / BLK_SIZE; cnt++)
    {
        compareptr = (unsigned long long*)buffer;
        for (i = 0; i < BLK_SIZE; i = i + sizeof(unsigned long long))
        {
            ptrcnt++;
            *compareptr = ptrcnt;
            compareptr++;
        }
        if (file_handle)
        {
            write_result = fwrite(buffer, BLK_SIZE, 1, file_handle);
            if (write_result != 1)
            {
                printf("ERROR write_result \n");
            }
        }
    }
    if (file_handle) 
        fclose(file_handle);
    file_handle = NULL;
    if (buffer)
    {
        free(buffer);
        buffer = NULL;
    }
    return 0;
}


相关文章
|
3月前
|
Ubuntu Linux Shell
【Linux操作系统】探秘Linux奥秘:shell 编程的解密与实战
【Linux操作系统】探秘Linux奥秘:shell 编程的解密与实战
71 0
|
4月前
|
Go
高效Go语言编程:os包实用技术大揭示
高效Go语言编程:os包实用技术大揭示
46 0
|
7月前
|
存储 缓存 Linux
操作系统与内核、系统编程与应用编程
操作系统与内核、系统编程与应用编程
64 0
|
7月前
|
Linux Shell Go
《Linux操作系统编程》第四章 屏幕编程器vi : 了解屏幕编辑器vi的概述和基本操作命令
《Linux操作系统编程》第四章 屏幕编程器vi : 了解屏幕编辑器vi的概述和基本操作命令
63 0
|
7月前
|
Linux Shell Go
《Linux操作系统编程》 第五章 文件和文件系统: 了解文件和文件系统的概念和特性,掌握Linux文件系统的基本操作
《Linux操作系统编程》 第五章 文件和文件系统: 了解文件和文件系统的概念和特性,掌握Linux文件系统的基本操作
71 0
|
7月前
|
存储 算法 Unix
《Linux操作系统编程》第一章 操作系统引论:了解操作系统的发展、特征、功能以及操作系统结构
《Linux操作系统编程》第一章 操作系统引论:了解操作系统的发展、特征、功能以及操作系统结构
26 0
|
7月前
|
安全 Unix Linux
《Linux操作系统编程》第三章 Linux操作系统基础: 了解Linux操作系统的相关概念
《Linux操作系统编程》第三章 Linux操作系统基础: 了解Linux操作系统的相关概念
98 0
|
3月前
|
IDE Linux 开发工具
DP读书:鲲鹏处理器 架构与编程(十三)操作系统内核与云基础软件
DP读书:鲲鹏处理器 架构与编程(十三)操作系统内核与云基础软件
70 1
|
9月前
|
Linux C语言
实验 线程编程-加1操作为什么会出错?【操作系统】
实验 线程编程-加1操作为什么会出错?【操作系统】
83 1
|
6月前
|
传感器 机器人 C++
机器人操作系统ROS 编程开发--详细总结
最近工作涉及到自动驾驶的,需要学习ROS,学习中总结了一些知识点,分享给大家。 机器人操作系统ROS,是一种分布式处理框架(又名Nodes),ROS常用C++和python编程语言开发;(这里项目开发采用C++ 11版本)。ROS的点对点设计以及服务和节点管理器等机制,可以分散由计算机视觉和语音识别等功能带来的实时计算压力,能够适应多机器人遇到的挑战。ROS免费并且开源。
379 0