一文搞定文件的读写操作

3 篇文章 0 订阅
3 篇文章 0 订阅
本文详细介绍了C语言、C++和Java中文件的操作流程,包括定义文件指针、不同权限下的文件打开、使用fgets/fputs/fclose进行读写、流的概念以及字节流和字符流的区别,还涉及了文件的序列化与反序列化过程。
摘要由CSDN通过智能技术生成

文件的操作

C

C语言中,文件的读取操作流程如下:

  1. 定义一个文件的指针
  2. 将指针指向需要打开的文件,并且赋予该指针权限(读,写,追加)
  3. 然后开始向文件写/读数据

打开文件

定义文件指针:FILE *fp = NULL;

给文件指针赋值,并赋予权限: fp = fopen(path, "r");,这里的path为文件的路径,r表示赋予的权限,更多的权限如下。

文件的读写权限:

模式字符串解释
r只读方式打开文件,文件必须存在。
w只写方式打开文件,如果文件存在则清空内容,如果文件不存在则创建。
a追加方式打开文件,如果文件不存在则创建
r+读写方式打开文件,文件必须存在。
w+读写方式打开文件,如果文件存在则清空内容,如果文件不存在则创建。
a+读写方式打开文件,如果文件不存在则创建,并总是追加到文件末尾。

读取文件(fgets()):

fgets()的第一个参数表示需要将文件数据写入的地址,可以为一个指针/数组,第二个参数表示需要写入数据的大小,第三个参数表示文件指针。

例子:
char data[255];   // 定义写入数据的地址
printf("文件内容为:\n");
while (fgets(data, sizeof(data), fp) != NULL) {   // 进行循环读取文件,直到读到文件的最后位置
    printf("%s", data);
}

写入文件(fputs()

写入文件使用fputs(),其参数有两个,第一个参数表示要写入的数据,第二个参数表示要写入的文件。

关闭文件(fclose()):

关闭文件使用fclose(fp)进行关闭,其参数为要关闭的文件指针。

实例

#include<stdio.h>
#include<string.h>

// 定义文件指针
FILE *fp = NULL; 

char buff[255];
// 文件的读取
int readFile(char* path){
	fp = fopen(path, "r");
	if(fp == NULL){
		printf("无法打开文件\n");
		return 0;
	}
	char data[255];
	printf("文件内容为:\n");
    while (fgets(data, sizeof(data), fp) != NULL) {
        printf("%s", data);
    }

	fclose(fp);
	printf("文件读取完毕\n");
	return 1;
}

// 文件的写入
int writeFile(char *path){
	fp = fopen(path, "w");
	
	if(fp == NULL){
		printf("无法打开文件! \n");
		return 0;
	}
	char data[255];
	gets(data);   // 从键盘中录入数据
	
	fputs(data, fp);
	printf("文件内容已经写入! \n"); 
	return 1;
}

// 文件的追加
int addFile(char* path){
	fp = fopen(path, "a");
	if(fp == NULL){
		printf("文件打开失败!\n");
		return 0;
	}
	char data[255];
	gets(data);   // 从键盘中读取文件输入到data中
	fputs(data, fp);
	
	fclose(fp);
	printf("已成功追加内容到文件! \n");
	return 1;
} 

int main(){
	char* path = "../tmp.txt";
	readFile("../tmp.txt");
//	writeFile("../new.txt");
//	addFile(path);
	return 0;
} 

C++

C++使用流的形式对文件进行读写操作。

C++文件的读取操作流程如下:

  1. 创建流对象。
  2. 打开文件进行读、写、追加操作。
  3. 关闭文件流。

创建流对象,一共有三种流方式:

流对象解释
ofstream写文件
ifstream写文件
fstream读写文件

打开文件,使用open方法进行打开文件, 其语法格式为:file.open ("文件路径" ,打开模式),其中file是一个流对象。

六种模式:

常量解释
ios::app每次写入前寻位到流结尾
ios::binary以二进制模式打开
ios::in只读模式打开
ios::out只写模式打开
ios::trunc在打开后舍弃流的内容
ios::ate打开后立即寻位到流结尾

文件的读写操作:

最简单的方式是直接使用file<<...;file>>...;两个方法进行输入输出流操作。

关闭流:

使用file.close();可以直接关闭流,其中file表示一个流对象。

实例

// c++的读写操作
#include<iostream>
#include<string>
#include<fstream>
using namespace std;

// 文件的读取操作
int readFile(string path){
	ifstream f;  //	也可使用:fstream f;

	string data;
	
	f.open(path);
	if(!f.is_open()){
		cout<<"无法打开文件!"<<endl;
		return 0;
	}
	
	cout<<"读取文件的内容为:"<<endl;
	while(getline(f, data)){
		cout<<data;
	}
	
	f.close();
	cout<<"文件读取完毕!"<<endl; 
	return 1;
}


// 文件的写入操作
int writeFile(string path){
	ofstream f;  //	也可使用:fstream f;
	string st = "这是一个测试字符串\n"; 
	f.open(path, ios::out);
	if(!f.is_open()){
		cout<<"无法打开文件!"<<endl;
		return 0;
	}
	f<<"张三: 男"<<endl;
	f<<"李四: 男"<<endl;
	f<<st;
	cout<<"文件写入完毕!"<<endl; 
	f.close();
	return 1;
}

// 文件的追加操作
int addFile(string path){
	ofstream f;  //	也可使用:fstream f;
	f.open(path, ios::app);
	if(!f.is_open()){
		cout<<"无法打开文件!"<<endl;
		return 0;
	}
	f<<"王五:男"<<endl;
	f<<"赵六:男"<<endl;
	char *st = "王红:女\n";
	f<<st;
	cout<<"文件追加完毕!"<<endl;
	f.close();
	return 1;
}


int main(){
	string path = "../tmp.txt";
	readFile(path);
//	writeFile("../new.txt");
//	addFile("../new.txt");
	return 0;
} 

/*
打开方式:
ios::in    只读 
ios::out   只写 
ios::ate   指针指向文件末尾 
ios::app   追加 
ios::trunc  如果原文件存在先删除在创建 
ios::binary   二进制方式打开文件 
*/

/*
文件操作的三大类型:
ofstream  :写操作 
ifstream  :读操作 
fstream   :读写操作 
*/

Java

Java文件的读写操作有两种方式,分别是字节流字符流,其最大区别在于:字节流无法读取中文,包括中文符号,而字符流可以读取中文包括中文符号。

字节流

整体流程:

  1. new一个文件对象。
  2. 使用流的方式打开文件对象。
  3. 进行读或写文件。
  4. 关闭文件
打开文件

new一个文件对象:File f = new File(path);

使用流的方式打开文件对象,有两种方式:

  1. 输入流:FileInputStream
  2. 输出流:FileOutputStream
读取(写入)文件

读取文件操作finp.read()

写入文件操作:要先将写入的数据转换为二进制流形式。

byte[] buff = this.data.getBytes();

fout.write(buff);
关闭文件

直接使用close()方法关闭文件即可,如:fout.close();

字符流

整体流程:

  1. 初始化文件
    1. new一个文件对象
    2. 读取文件对象
    3. 使用字符流读取文件对象
  2. 进行读或写文件
  3. 关闭文件
初始化文件:
  1. 初始化读取文件:
File f = new File(this.path);
FileReader fr = null;   // 文件读取对象
BufferedReader fbr = null;   // 字符流读取对象

fr = new FileReader(f);
fbr = new BufferedReader(fr);
  1. 初始化写入文件:
File f = new File(path);
FileWriter fw = null;
BufferedWriter fwb = null;

fw = new FileWriter(f);
fwb = new BufferedWriter(fw);
进行读或写文件:
  1. 进行读取操作
str = fbr.readLine()   // 如果执行到文件末尾,则返回null
  1. 进行写入操作
fwb.write(cdata[i]);
fwb.newLine();  // 换行操作
关闭文件

注意关闭的顺序!!!

fbr.close();  // 先关闭流对象
fr.close();   // 再关闭文件读取对象

序列化与反序列化

序列化

序列化可以将java对象进行存储。

// 序列化:用于存储java对象
public int seqToFile(String path) {
    Set<String> set = new HashSet<>();
    set.add("one");
    set.add("tow");
    set.add("three");
    File f = new File(path);
    FileOutputStream fo = null;
    ObjectOutputStream fob = null;
    try {
        fo = new FileOutputStream(f);
        fob = new ObjectOutputStream(fo);   // 进行序列化
        fob.writeObject(set);  // 写入Java对象
        System.out.println("序列化文件写入完毕!");
    } catch (Exception e){
        e.printStackTrace();
    }finally {
        try {
            fob.close();
            fo.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    return 0;
}
反序列化

反序列化可以从文件中读取java对象。

// 进行反序列化
public int FileToseq(String path){
    Set<String> set = null;
    File f = new File(path);
    FileInputStream fi = null;
    ObjectInput fio = null;
    try {
        fi = new FileInputStream(f);
        fio = new ObjectInputStream(fi);
        Object obj = fio.readObject();   // Object类型可以接收所有java对象
        set = (HashSet<String>) obj;
        System.out.println("反序列化读写完毕!");
    } catch (Exception e){
        e.printStackTrace();
    }finally {
        try {
            fio.close();
            fi.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    // 进行输出set集合
    for(String i :set){
        System.out.println(i);
    }

    return 0;
}

实例

import javax.swing.*;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

class WRClass {
    public String path;  // 原文件的路径
    public String new_path;  // 新建文件的路径
    public String data = "This is a new txt.\n";


    public WRClass(String path, String new_path) {
        this.path = path;
        this.new_path = new_path;
    }

    // 创建文件
    public int CreateFile(String path) {
        File f = new File(path);
        if (f.exists()) {
            System.out.println("文件已存在!");
            return 1;
        } else {
            try {
                f.createNewFile();
                System.out.println("文件创建成功");
            } catch (Exception e) {

            }
        }
        return 0;
    }

    // Stream流(字节流)  无法读取中文,包括中文符号
    // 文件的读操作
    public int ReadFile() {
        try {
            File f = new File(this.path);
            FileInputStream finp = new FileInputStream(f);
            for (int i = 0; i < f.length(); i++) {
                // 循环读取文件
                char ch = (char) (finp.read());
                System.out.println(ch + ' ');
            }
            System.out.println("\n");
            finp.close();   // 进行关闭流
        } catch (Exception e) {
            System.out.println("文件打开失败!");
        }
        return 0;
    }

    // 文件的写操作
    public int WriteFile(String path) {
        File f = new File(path);
        try {
            FileOutputStream fout = new FileOutputStream(f);
            // 将字符转换为字节
            byte[] buff = this.data.getBytes();
            fout.write(buff);  // 写入文件
            try {
                fout.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            System.out.println("文件打开失败!");
        }

        return 0;
    }

    // Stream流(字符流) 可以读取中文字符
    // 文件的读取操作
    public int CReadFIle() {
        File f = new File(this.path);
        FileReader fr = null;   // 文件读取对象
        BufferedReader fbr = null;   // 字符流读取对象
        try {
            fr = new FileReader(f);
            fbr = new BufferedReader(fr);
            // 循环打印文件的每一行数据
            String str = null;
            while ((str = fbr.readLine()) != null) {
                System.out.println(str);
            }
            System.out.println("文件读取完毕!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fbr.close();
                fr.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return 0;
    }

    // 文件的写操作
    public int CWriteFile(String path) {
        String[] cdata = {"这是第一行数据", "这是第二行数据"};
        File f = new File(path);
        FileWriter fw = null;
        BufferedWriter fwb = null;

        try {
            fw = new FileWriter(f);
            fwb = new BufferedWriter(fw);
            for (int i = 0; i < cdata.length; i++) {
                fwb.write(cdata[i]);
                fwb.newLine();  // 换行操作
            }
            System.out.println("文件写入完毕!");
        } catch (Exception e) {

        } finally {
            try {
                fwb.close();
                fw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    // 序列化:用于存储java对象
    public int seqToFile(String path) {
        Set<String> set = new HashSet<>();
        set.add("one");
        set.add("tow");
        set.add("three");
        File f = new File(path);
        FileOutputStream fo = null;
        ObjectOutputStream fob = null;
        try {
            fo = new FileOutputStream(f);
            fob = new ObjectOutputStream(fo);   // 进行序列化
            fob.writeObject(set);  // 写入Java对象
            System.out.println("序列化文件写入完毕!");
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                fob.close();
                fo.close();
            } catch (Exception e){
                e.printStackTrace();
            }
        }

        return 0;
    }

    // 进行反序列化
    public int FileToseq(String path){
        Set<String> set = null;
        File f = new File(path);
        FileInputStream fi = null;
        ObjectInput fio = null;
        try {
            fi = new FileInputStream(f);
            fio = new ObjectInputStream(fi);
            Object obj = fio.readObject();   // Object类型可以接收所有java对象
            set = (HashSet<String>) obj;
            System.out.println("反序列化读写完毕!");
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                fio.close();
                fi.close();
            } catch (Exception e){
                e.printStackTrace();
            }
        }
        // 进行输出set集合
        for(String i :set){
            System.out.println(i);
        }

        return 0;
    }
}


public class Java {

    public static void main(String[] args) {
        String path = "../tmp.txt";
        String new_path = "../new.txt";
        String java_new_path = "../jnew.txt";
        WRClass wr = new WRClass(path, new_path);
//        wr.CreateFile(java_new_path);
//        wr.CReadFIle();
//        wr.WriteFile(java_new_path);
//        wr.CReadFIle();
//        wr.CWriteFile(java_new_path);
//        wr.seqToFile(java_new_path);
        wr.FileToseq(java_new_path);
    }
}

Python

Python文件的读写操作非常简便,其流程如下

  1. 直接将一个对象赋值为一个打开的文件,打开文件使用open(path, model)方法。
  2. 进行文件的读或写操作。
  3. 关闭文件。

打开文件

打开文件使用open(path, model)方法,第一个参数为文件的路径,第二个参数为文件的读写权限,具体的权限如下:

文件的读写权限:

模式字符串解释
w只写
r只读
a追加
b二进制文件

文件的读写权限可以任意组合

文件的读写操作:

方法解释
f.readline()按行读取文件中的内容,遇到换行符自动结束读取,进入等待状态(等待下次的读取)
f.seek(0)定位指针
f.readlines()读取所有行,并将每一行作为一个元素存放到列表中。
f.writelines(self.data)向文件写入所有行
f.write(self.st)向文件写入所有文件
f.read()读取所有数据

关闭文件

直接调用close()方法。

对于文件的读写操作可以使用with语句进行操作,这样做的好处是不用在关闭文件的流了,可以防止由于疏忽造成的文件误关闭的意外。

实例

''''
文件的读取操作
w : 只写
r : 只读
a : 追加
b : 二进制文件
'''


class WRFile(object):
    def __init__(self, path, new_path):
        self.path = path
        self.new_path = new_path
        self.data = ['line 1\n', 'line 2\n', 'line3\n']
        self.st = "This is a new txt.\n"

    def readFile(self, flag: int = 1):
        '''
        读取文件
        :return:
        '''
        if flag == 1:
            # 读取整个文件
            with open(self.path, 'r') as f:
                content = f.read()
                # content = f.read(10) #  读取前10个字符
                # f.seek(0)  # 将文件指针重新移动到开头
                print(content)
        elif flag == 2:
            # 按行读取文件
            with open(self.path, 'r') as f:
                line = "test"
                while line:
                    line = f.readline()
                    print(line)
        elif flag == 3:
            # 读取所有行
            with open(self.path, 'r') as f:
                lines = f.readlines()  # 读取到一个列表中
                for line in lines:
                    print(line)

    def writeFile(self, flag: int = 1):
        '''
        写入文件
        :return:
        '''
        if flag == 1:
            # 写入多行文件
            with open(self.new_path, 'w') as f:
                f.writelines(self.data)
        elif flag == 2:
            # 写入字符串
            with open(self.new_path, 'w') as f:
                f.write(self.st)

    def addFile(self, flag: int = 1):
        if flag == 1:
            with open(self.new_path, 'a') as f:
                f.write(self.st)
        if flag == 2:
            f = open(self.new_path, 'a')
            f.write(self.st)
            f.close()

    def __del__(self):   # 当类对象被销毁时直接调用该方法。
        print("程序执行完毕!!!")


if __name__ == '__main__':
    File = WRFile(path="../tmp.txt", new_path="../new.txt")
    File.readFile(flag=2)
    # File.writeFile(flag=2)
    # File.addFile(flag=2)
  • 29
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值