文件的操作
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 = 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)