文件的操作
C
C
语言中,文件的读取操作流程如下:
- 定义一个文件的指针
- 将指针指向需要打开的文件,并且赋予该指针权限(读,写,追加)
- 然后开始向文件写/读数据
打开文件
定义文件指针: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++
文件的读取操作流程如下:
- 创建流对象。
- 打开文件进行读、写、追加操作。
- 关闭文件流。
创建流对象,一共有三种流方式:
流对象 | 解释 |
---|---|
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
文件的读写操作有两种方式,分别是字节流和字符流,其最大区别在于:字节流无法读取中文,包括中文符号,而字符流可以读取中文包括中文符号。
字节流
整体流程:
- new一个文件对象。
- 使用流的方式打开文件对象。
- 进行读或写文件。
- 关闭文件
打开文件
new
一个文件对象:File f = new File(path);
使用流的方式打开文件对象,有两种方式:
- 输入流:
FileInputStream
- 输出流:
FileOutputStream
读取(写入)文件
读取文件操作:finp.read()
写入文件操作:要先将写入的数据转换为二进制流形式。
byte[] buff = this.data.getBytes();fout.write(buff);
关闭文件
直接使用close()
方法关闭文件即可,如:fout.close();
字符流
整体流程:
- 初始化文件
- new一个文件对象
- 读取文件对象
- 使用字符流读取文件对象
- 进行读或写文件
- 关闭文件
初始化文件:
- 初始化读取文件:
File f = new File(this.path);
FileReader fr = null; // 文件读取对象
BufferedReader fbr = null; // 字符流读取对象fr = new FileReader(f);
fbr = new BufferedReader(fr);
- 初始化写入文件:
File f = new File(path);
FileWriter fw = null;
BufferedWriter fwb = null;fw = new FileWriter(f);
fwb = new BufferedWriter(fw);
进行读或写文件:
- 进行读取操作
str = fbr.readLine() // 如果执行到文件末尾,则返回null
- 进行写入操作
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
文件的读写操作非常简便,其流程如下:
- 直接将一个对象赋值为一个打开的文件,打开文件使用
open(path, model)
方法。- 进行文件的读或写操作。
- 关闭文件。
打开文件
打开文件使用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 = pathself.new_path = new_pathself.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)