各种语言的文件读写方法

本文介绍了文件在Linux中的表示方式,包括file结构体和inode结构体,以及文件的打开、读写操作。同时,对比了Windows下的文件操作,如CreateFile和ReadFile等。还提到了C语言中处理文本和二进制模式的区别,以及在不同操作系统下的差异。
摘要由CSDN通过智能技术生成

文件数据的表示方式

file的定义如下,open操作也就是建立这个file对象,因此file是进程维护的对象。

struct file {
    union {
        struct llist_node    fu_llist;
        struct rcu_head      fu_rcuhead;
    } f_u;
    struct path              f_path;
    #define f_dentry          f_path.dentry
    struct inode             *f_inode;      /* cached value */
    const struct file_operations*f_op;      /* 和文件关联的操作*/

    /*
    * Protects f_ep_links, f_flags.
    * Must not be taken from IRQ context.
    */
    spinlock_t          f_lock;
    atomic_long_t       f_count;
    unsigned int        f_flags;       /*文件标志,如O_RDONLY、O_NONBLOCK、O_SYNC*/
    fmode_t             f_mode;        /*文件读/写模式,FMODE_READ和FMODE_WRITE*/
    struct mutex        f_pos_lock;
    loff_t              f_pos;         /* 当前读写位置 */
    struct fown_struct  f_owner;
    const struct cred   *f_cred;
    struct file_ra_statef_ra;

    u64                f_version;
    #ifdef CONfiG_SECURITY
    void         *f_security;
    #endif
    /* needed for tty driver, and maybe others */
    void         *private_data;        /*文件私有数据*/

    #ifdef CONfiG_EPOLL
    /* Used by fs/eventpoll.c to link all the hooks to this file */
    struct list_head     f_ep_links;
    struct list_head     f_tfile_llink;
    #endif                              /* #ifdef CONfiG_EPOLL */
    struct address_space*f_mapping;
} __attribute__((aligned(4)));      /* lest something weird decides that 2 is OK */

inode的定义如下,inode是由文件系统维护的数据:

struct inode {
    ...
    umode_t i_mode;            /* inode的权限 */ 
    uid_t i_uid;               /* inode拥有者的id */ 
    gid_t i_gid;               /* inode所属的群组id */ 
    dev_t i_rdev;              /* 若是设备文件,此字段将记录设备的设备号 */ 
    loff_t i_size;             /* inode所代表的文件大小 */ 

    struct timespec i_atime;   /* inode最近一次的存取时间 */ 
    struct timespec i_mtime;   /* inode最近一次的修改时间 */ 
    struct timespec i_ctime;   /* inode的产生时间 */ 

    unsigned int        i_blkbits;
    blkcnt_t        i_blocks;  /* inode所使用的block数,一个block为512 字节 */ 
    union {
      struct pipe_inode_info  *i_pipe;
      struct block_device *i_bdev;
                               /* 若是块设备,为其对应的block_device结构体指针 */ 
      struct cdev *i_cdev;     /* 若是字符设备,为其对应的cdev结构体指针 */ 
    }  
    ...
};

Linux-glibc

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define BUFSIZE 512

int main()
{
    char buffer[BUFSIZE];
    int fd = open("/tmp/test.txt", O_RDONLY);
    ssize_t n;

    if (fd == -1) {
        perror("open");
        return -1;
    }

    while ((n = read(fd, buffer, BUFSIZE)) > 0) {
        if (write(STDOUT_FILENO, buffer, n) == -1) {
            perror("write");
            close(fd);
            return -1;
        }
    }

    close(fd);

    return 0;
}

Windows读写文件

#include <windows.h>
#include <iostream>

int main()
{
    // 创建文件句柄
    HANDLE hFile = CreateFile(TEXT("test.txt"), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "CreateFile failed, error code: " << GetLastError() << std::endl;
        return 1;
    }

    // 写入数据
    const char* data = "Hello, world!";
    DWORD bytesWritten;
    if (!WriteFile(hFile, data, strlen(data), &bytesWritten, NULL)) {
        std::cerr << "WriteFile failed, error code: " << GetLastError() << std::endl;
        CloseHandle(hFile);
        return 1;
    }

    // 读取数据
    char buf[1024];
    DWORD bytesRead;
    if (!ReadFile(hFile, buf, sizeof(buf), &bytesRead, NULL)) {
        std::cerr << "ReadFile failed, error code: " << GetLastError() << std::endl;
        CloseHandle(hFile);
        return 1;
    }
    buf[bytesRead] = '\0';
    std::cout << "Read data: " << buf << std::endl;

    // 关闭文件句柄
    CloseHandle(hFile);

    return 0;
}

C语言

C提供两种文件模式:文本模式和二进制模式。
之所以会提供两种模式,是因为不同的平台虽然字符集是相同的,但是换行符不同,在Windows上换行符是\r\n,在Linux上换行符是\n。所以C语言为了让数据能够适应平台,就必须在各个平台间进行转换。

在C语言中,文件读写操作主要涉及以下函数:

  • fopen: 打开文件并返回文件指针。
  • fclose: 关闭文件。
  • fgetc/getc: 从文件中读取一个字符。
  • fgets: 从文件中读取一行数据。
  • fputc/putc: 将一个字符写入文件。
  • fputs: 将字符串写入文件。
  • fprintf: 格式化输出到文件。
  • fscanf: 从文件中按格式读取数据。
int ch; 
FILE *fp;
fp = fopen("a.txt","r");
ch = getc(fp);

fclose(fp);

image.png

FILE *fp;
int fd;

fd = open("a.txt","r");
fp = fdopen(fd,"rb");
fgets(buffer, sizeof(buffer), file);
fputs("Hello, World!", file);

C++

#include <iostream>
#include <fstream>

int main() {
    // 打开文件
    std::ifstream infile("example.txt");

    // 读取文件内容
    std::string line;
    while (std::getline(infile, line)) {
        std::cout << line << std::endl;
    }

    // 关闭文件
    infile.close();

    return 0;
}

python

# 打开文件
file = open('example.txt', 'w')

# 写入文件
file.write('Hello World!\n')
file.write('Goodbye World!\n')

# 关闭文件
file.close()

# 打开文件进行读取
file = open('example.txt', 'r')

# 读取文件
content = file.read()
print(content)

# 关闭文件
file.close()

Qt

#include <QFile>
#include <QTextStream>

int main()
{
    // 写入文件
    QFile file("test.txt");
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream out(&file);
        out << "Hello, world!\n";
        file.close();
    }

    // 读取文件
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream in(&file);
        QString line = in.readLine();
        qDebug() << line;
        file.close();
    }

    return 0;
}

文本模式和二进制模式

文本模式和二进制模式只在Windows下生效,因为只有Windows会将文本的结束符添加为\r\n,而c语言和linux中默认文本的换行符就是\n,处理文本和处理二进制行为是一致的,所以linux系统调用中不存在设置二进制模式和文本模式的标志位,只有Windows下,c语言才需要将\r\n结束符转换为\n进行处理。

所以二进制模式只在Windows系统,c语言等其他语言情况下才有。

在linux系统上,使用c语言设置二进制模式和不设置二进制模式效果是一样的,都是原样读写,包括\r也是原样读写。

vim 会自动识别dos文件:
image.png

如果以二进制读取则:

vim -b <文件>

image.png

查看二进制格式:

hexdump -C <文件>
00000000  5b 41 75 74 6f 52 75 6e  2e 41 6d 64 36 34 5d 0d  |[AutoRun.Amd64].|
00000010  0a 6f 70 65 6e 3d 73 65  74 75 70 2e 65 78 65 0d  |.open=setup.exe.|
00000020  0a 69 63 6f 6e 3d 73 65  74 75 70 2e 65 78 65 2c  |.icon=setup.exe,|
00000030  30 0d 0a 0d 0a 5b 41 75  74 6f 52 75 6e 5d 0d 0a  |0....[AutoRun]..|
00000040  6f 70 65 6e 3d 73 6f 75  72 63 65 73 5c 53 65 74  |open=sources\Set|
00000050  75 70 45 72 72 6f 72 2e  65 78 65 20 78 36 34 0d  |upError.exe x64.|
00000060  0a 69 63 6f 6e 3d 73 6f  75 72 63 65 73 5c 53 65  |.icon=sources\Se|
00000070  74 75 70 45 72 72 6f 72  2e 65 78 65 2c 30 0d 0a  |tupError.exe,0..|
00000080

会看到^M其实是0a

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多弗朗强哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值