Python 文件基础科普与文件打开技术详解

本文详细讲解了Python中的文件操作,包括基础概念、打开技术、读写、异常处理、上下文管理器、二进制文件处理、目录操作等,为理解和实践文件操作提供了全面指南。
摘要由CSDN通过智能技术生成

👽发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。

Python 文件基础科普与文件打开技术详解

在Python编程中,文件操作是一项基础而重要的任务。无论是读取数据、写入文件还是进行其他文件处理操作,都需要对文件基础知识有一定的了解。在本文中,我们将首先介绍Python文件的基础概念,然后深入探讨文件打开的技术,附带代码实例和详细解析。

IMG_20231006_183505

文件基础科普

文件的概念

文件是存储在计算机上的数据集合,可以包含文本、图像、音频等各种信息。在Python中,文件可以分为文本文件和二进制文件。文本文件是由字符组成,而二进制文件则包含了更为复杂的数据格式。

文件路径

文件路径是文件在计算机中的位置表示。在不同的操作系统中,文件路径的表示方式可能有所不同。常见的文件路径包括绝对路径和相对路径。绝对路径从根目录开始,而相对路径是相对于当前工作目录的路径。

文件打开技术

打开文件的基本语法

在Python中,使用open()函数来打开文件。open()函数接受文件名和打开模式作为参数,返回一个文件对象。

file = open('example.txt', 'r')

上述代码以只读模式(‘r’)打开名为’example.txt’的文件,并将文件对象赋值给变量file

文件打开模式

  • 'r':只读模式,用于读取文件内容。
  • 'w':写入模式,用于写入文件内容。如果文件存在,会清空文件内容;如果文件不存在,会创建新文件。
  • 'a':追加模式,用于在文件末尾追加内容。如果文件不存在,会创建新文件。
  • 'b':二进制模式,用于处理二进制文件,例如图片或音频文件。

关闭文件

使用完文件后,应该及时关闭以释放系统资源。

file.close()

代码实例

接下来,让我们看一个完整的文件打开和关闭的代码实例:

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

# 写入内容
file.write('Hello, this is an example.')

# 关闭文件
file.close()

代码解析

  1. 使用open()函数打开文件,指定文件名为’example.txt’,打开模式为写入模式(‘w’)。
  2. 通过write()方法向文件中写入文本内容。
  3. 使用close()方法关闭文件。

以上是一个简单的文件写入示例,通过类似的方式,可以使用不同的打开模式实现文件的读取、追加等操作。

通过深入了解文件基础知识和文件打开技术,我们可以更灵活地处理文件操作,为实际项目中的数据处理提供强大的支持。在实际应用中,请根据需求选择合适的文件打开模式,并注意及时关闭文件以避免资源泄漏。希望本文对你理解Python文件操作提供了帮助。

文件读取与异常处理

读取文件内容

在前述示例中,我们演示了文件写入操作。现在,让我们看一下如何读取文件内容。使用只读模式(‘r’)打开文件,然后可以通过read()方法读取文件的全部内容:

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

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

# 关闭文件
file.close()

逐行读取文件

如果文件很大,逐行读取更为高效。使用readline()方法可以逐行读取文件:

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

# 逐行读取文件内容
line = file.readline()
while line:
    print(line.strip())  # 使用strip()方法去除行尾换行符
    line = file.readline()

# 关闭文件
file.close()

异常处理

文件操作可能引发异常,例如文件不存在、权限不足等。为了增强代码的健壮性,应该使用tryexcept块进行异常处理:

try:
    file = open('example.txt', 'r')
    content = file.read()
    print(content)
    file.close()
except FileNotFoundError:
    print("文件不存在")
except PermissionError:
    print("没有文件访问权限")
except Exception as e:
    print(f"发生了未知错误:{e}")
finally:
    if 'file' in locals() and not file.closed:
        file.close()

上述代码使用了tryexceptfinally块,确保无论发生什么异常,都能正确地关闭文件。

文件写入进阶与上下文管理器

文件写入进阶

在前述写入文件的示例中,我们使用了write()方法将内容写入文件。现在,让我们看一下如何更灵活地进行文件写入,并探讨一些高级的写入技巧。

使用with语句

Python提供了with语句,可以更方便地管理文件的打开和关闭。使用with语句,无需手动调用close()方法,系统会在离开with块时自动关闭文件。

# 使用with语句写入文件
with open('example.txt', 'w') as file:
    file.write('Hello, this is an example.')
写入多行

如果需要写入多行内容,可以使用writelines()方法。该方法接受一个字符串列表,每个字符串代表一行文本。

# 使用writelines写入多行
lines = ['Line 1\n', 'Line 2\n', 'Line 3\n']
with open('example.txt', 'w') as file:
    file.writelines(lines)

上下文管理器

上下文管理器是一个支持with语句的对象,用于管理资源的获取和释放。在文件操作中,open()函数返回的文件对象本身就是一个上下文管理器,但也可以使用contextlib模块的contextmanager装饰器自定义上下文管理器。

from contextlib import contextmanager

@contextmanager
def custom_context_manager():
    # 在进入with语句块时执行的代码
    print("Entering the context")
    yield  # 生成器的yield语句之前的代码为__enter__方法
    # 在离开with语句块时执行的代码
    print("Exiting the context")

# 使用自定义上下文管理器
with custom_context_manager():
    print("Inside the context")

在上述例子中,进入和退出上下文时会打印相应的消息。yield语句之前的代码为__enter__方法,之后的代码为__exit__方法。

文件读写二进制数据

在处理二进制文件时,需要以二进制模式(‘rb’或’wb’)打开文件。以下是一个读取和写入二进制文件的示例:

# 读取二进制文件
with open('binary_data.bin', 'rb') as file:
    binary_content = file.read()
    print(binary_content)

# 写入二进制文件
binary_data = b'\x48\x65\x6C\x6C\x6F'  # ASCII编码的"Hello"
with open('binary_data.bin', 'wb') as file:
    file.write(binary_data)

在读取二进制文件时,使用read()方法获取二进制数据。在写入二进制文件时,通过write()方法写入二进制数据。

文件定位与截断

在文件处理过程中,有时我们需要在文件中定位到特定位置进行读取或写入操作。此外,文件截断是一种在指定位置截断文件内容的操作。让我们一起深入了解这两个方面的技术。

文件定位

使用seek()方法可以在文件中定位到指定的位置。seek(offset, whence)接受两个参数,offset表示偏移量,whence表示基准位置。基准位置有三个值:

  • 0:从文件开头计算偏移量(默认值)。
  • 1:从当前位置计算偏移量。
  • 2:从文件末尾计算偏移量。
# 文件定位示例
with open('example.txt', 'r') as file:
    file.seek(5)  # 移动到文件第6个字节处
    content = file.read()
    print(content)

文件截断

使用truncate()方法可以截断文件内容,保留指定长度的内容。如果不传递参数,则截断当前位置之后的内容。

# 文件截断示例
with open('example.txt', 'r+') as file:
    file.seek(10)  # 定位到第11个字节
    file.truncate()  # 截断文件,保留前10个字节
    content = file.read()
    print(content)

在上述示例中,文件被截断后,读取的内容只包括前10个字节。

示例:在文件中插入内容

结合文件定位和截断的技术,我们可以在文件中间插入内容。以下是一个在指定位置插入文本的示例:

# 在文件中间插入内容示例
with open('example.txt', 'r+') as file:
    position = 5
    content = file.read()
    file.seek(position)
    file.write("Inserted Text ")
    file.write(content)

在这个示例中,我们首先读取文件内容,然后将文件指针移动到指定位置,插入新的文本,最后写入原始内容。这样就在文件中间成功插入了内容。

文件和目录操作

除了基本的文件读写和定位技术外,Python还提供了丰富的文件和目录操作功能。这包括检查文件/目录是否存在、创建目录、删除文件/目录等操作。让我们一起学习这些常用的文件和目录管理技术。

检查文件/目录是否存在

在进行文件和目录操作之前,通常需要先检查它们是否存在。使用os模块的path模块可以方便地进行这些检查。

import os

# 检查文件是否存在
file_path = 'example.txt'
if os.path.exists(file_path):
    print(f"文件 '{file_path}' 存在")
else:
    print(f"文件 '{file_path}' 不存在")

# 检查目录是否存在
directory_path = 'my_directory'
if os.path.exists(directory_path):
    print(f"目录 '{directory_path}' 存在")
else:
    print(f"目录 '{directory_path}' 不存在")

创建目录

使用os模块的mkdir()方法可以创建新的目录。

import os

# 创建目录
new_directory = 'my_new_directory'
os.mkdir(new_directory)
print(f"目录 '{new_directory}' 已创建")

删除文件/目录

使用os模块的remove()方法可以删除文件,使用rmdir()方法可以删除目录。需要注意,删除目录时目录必须为空,否则会引发OSError

import os

# 删除文件
file_to_delete = 'file_to_delete.txt'
os.remove(file_to_delete)
print(f"文件 '{file_to_delete}' 已删除")

# 删除目录
directory_to_delete = 'directory_to_delete'
os.rmdir(directory_to_delete)
print(f"目录 '{directory_to_delete}' 已删除")

遍历目录内容

使用os模块的listdir()方法可以获取目录中的文件和子目录列表。

import os

# 遍历目录内容
directory_path = 'my_directory'
contents = os.listdir(directory_path)

print(f"目录 '{directory_path}' 中的内容:")
for item in contents:
    print(item)

示例:复制文件

结合文件读写和目录操作技术,我们可以实现文件的复制操作。

import shutil

# 复制文件
source_file = 'source.txt'
destination_file = 'destination.txt'
shutil.copy(source_file, destination_file)
print(f"文件 '{source_file}' 已复制到 '{destination_file}'")

在这个示例中,使用shutil模块的copy()方法实现了文件的复制操作。

总结

本文深入介绍了Python中关于文件操作的基础知识和高级技术,以及文件和目录管理的一些常见操作。首先,我们学习了文件的基本概念、路径表示方法以及不同的文件打开模式。随后,我们详细探讨了文件读取、写入、截断、定位等方面的技术,并介绍了上下文管理器的使用。文件的二进制操作也得到了涉及,增加了对处理图像、音频等二进制文件的能力。

进一步,我们讨论了文件和目录的存在性检查、创建、删除,以及遍历目录内容的方法。这些操作为文件系统的组织和管理提供了灵活性。最后,通过一个文件复制的示例,我们展示了如何结合不同的技术完成更复杂的任务。

通过学习本文,读者应该能够对Python中文件处理的基本知识和高级技术有一个全面的了解。文件操作是编程中常见而重要的一部分,对于数据处理和项目开发具有重要意义。希望本文能够激发你对Python文件操作的兴趣,并为你在实际项目中的文件处理提供了实用的技巧和方法。

#include <stdio.h> #include <memory.h> #include <string> #include <iostream> using namespace std; //1代表普通文件2代表目录文件0表示空文件 #define GENERAL 1 #define DIRECTORY 2 #define HXSH 0 struct FCB { char fname[16]; //文件名 char type; int size; //文件大小 int fatherBlockNum; //当前的父目录盘块号 int currentBlockNum; //当前的盘块 void initialize() { strcpy(fname,"\0"); type = HXSH; size =0; fatherBlockNum = currentBlockNum = 0; } }; /*常量设置*/ const char* FilePath = "C:\\myfiles"; const int BlockSize = 512; //盘块大小 const int OPEN_MAX = 5; //能打开最多的文件数 const int BlockCount = 128; //盘块数 const int DiskSize = BlockSize*BlockCount; //磁盘大小 const int BlockFcbCount = BlockSize/sizeof(FCB);//目录文件的最多FCB数 int OpenFileCount = 0; struct OPENLIST //用户文件打开表 { int files; //当前打开文件数 FCB f[OPEN_MAX]; //FCB拷贝 OPENLIST() { files=0; for(int i=0;i<OPEN_MAX;i++){ f[i].fatherBlockNum=-1;//为分配打开 f[i].type=GENERAL; } } }; /*-------------目录文件结构---------------*/ struct dirFile { struct FCB fcb[BlockFcbCount]; void init(int _FatherBlockNum,int _CurrentBlockNum,char *name)//父块号,当前块号,目录名 { strcpy(fcb[0].fname,name); //本身的FCB fcb[0].fatherBlockNum=_FatherBlockNum; fcb[0].currentBlockNum=_CurrentBlockNum; fcb[0].type=DIRECTORY; //标记目录文件 for(int i=1;i<BlockFcbCount;i++){ fcb[i].fatherBlockNum=_CurrentBlockNum; //标记为子项 fcb[i].type=HXSH; // 标记为空白项 } } }; /**********************************************************************/ struct DISK { int FAT1[BlockCount]; //FAT1 int FAT2[BlockCount]; //FAT2 struct dirFile root; //根目录 char data[BlockCount-3][BlockSize]; void format() { memset(FAT1,0,BlockCount); //FAT1 memset(FAT2,0,BlockCount); //FAT2 FAT1[0]=FAT1[1]=FAT1[2]=-2; //0,1,2盘块号依次代表FAT1,FAT2,根目录区 FAT2[0]=FAT2[1]=FAT2[2]=-2; //FAT作备份 root.init(2,2,"C:\\");//根目录区 memset(data,0,sizeof(data));//数据区 } }; /*-----------------全局变量--------------------------*/ FILE *fp; //磁盘文件地址 char * BaseAddr; //虚拟磁盘空间基地址 string currentPath="C:\\\\"; //当前路径 int current=2; //当前目录的盘块号 string cmd; //输入指令 struct DISK *osPoint; //磁盘操作系统指针 char command[16]; //文件名标识 struct OPENLIST* openlist; //用户文件列表指针 /*-----------函数事先申明--------------------*/ int format(); int mkdir(char *sonfname); int rmdir(char *sonfname); int create(char *name); int listshow(); int delfile(char *name); int changePath(char *sonfname); int write(char *name); int exit(); int open(char *file); int close(char *file); int read(char *file); /*------------初始化-----------------------*/ int format() { current = 2; currentPath="C:\\\\"; //当前路径 osPoint->format();//打开文件列表初始化 delete openlist; openlist=new OPENLIST; /*-------保存到磁盘上myfiles--------*/ fp = fopen(FilePath,"w+"); fwrite(BaseAddr,sizeof(char),DiskSize,fp); fclose(fp); printf("----------------------------------------------------------\n\n"); return 1; } /*-----------------------创建子目录-------------------*/ int mkdir(char *sonfname) { //判断是否有重名 //寻找空白子目录项 //寻找空白盘块号 //当前目录下增加该子目录项 //分配子目录盘块,并且初始化 //修改fat表 int i,temp,iFAT; struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); /*--------为了避免该目录下同名文件夹--------*/ for(i = 1;i<BlockFcbCount;i++) { if(dir->fcb[i].type==DIRECTORY && strcmp(dir->fcb[i].fname,sonfname)==0 ) { printf("该文件夹下已经有同名的文件夹存在了!\n"); return 0; } } //查找空白fcb序号 for(i=1;i<BlockFcbCount;i++) { if(dir->fcb[i].type==HXSH) break; } if(i==BlockFcbCount) { printf("该目录已满!请选择新的目录下创建!\n"); return 0; } temp=i; for(i = 3;i < BlockCount;i++) { if(osPoint->FAT1[i] == 0) break; } if(i == BlockCount) { printf("磁盘已满!\n"); return 0; } iFAT=i; /*-------------接下来进行分配----------*/ osPoint->FAT1[iFAT]=osPoint->FAT2[iFAT] = 2; //2表示分配给下级目录文件 //填写该分派新的盘块的参数 strcpy(dir->fcb[temp].fname,sonfname); dir->fcb[temp].type=DIRECTORY; dir->fcb[temp].fatherBlockNum=current; dir->fcb[temp].currentBlockNum=iFAT; //初始化子目录文件盘块 dir=(struct dirFile*)(osPoint->data [iFAT-3]); //定位到子目录盘块号 dir->init (current,iFAT,sonfname);//iFAT是要分配的块号,这里的current用来指要分配的块的父块号 printf("---------------------------------------------------------------\n\n"); return 1; } /*-------删除当前目录下的文件夹--------*/ int rmdir(char *sonfname) { int i,temp,j;//确保当前目录下有该文件,并记录下该FCB下标 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i=1;i<BlockFcbCount;i++) { //查找该目录文件 if(dir->fcb[i].type==DIRECTORY && strcmp(dir->fcb[i].fname,sonfname)==0) { break; } } temp=i; if(i==BlockFcbCount) { printf("当前目录下不存在该子目录!\n"); return 0; } j = dir->fcb[temp].currentBlockNum; struct dirFile *sonDir; //当前子目录的指针 sonDir=(struct dirFile *)(osPoint->data [ j - 3]); for(i=1;i<BlockFcbCount;i++) //查找子目录是否为空目录 { if(sonDir->fcb[i].type!=HXSH) { printf("该文件夹为非空文件夹,为确保安全,请清空后再删除!\n"); return 0; } } /*开始删除子目录操作*/ osPoint->FAT1[j] = osPoint->FAT2[j]=0; //fat清空 char *p=osPoint->data[j-3]; //格式化子目录 memset(p,0,BlockSize); dir->fcb[temp].initialize(); //回收子目录占据目录项 printf("---------------------------------------------------------------\n\n"); return 1; } /*-----------在当前目录下创建文本文件---------------*/ int create(char *name) { int i,iFAT;//temp, int emptyNum = 0,isFound = 0; //空闲目录项个数 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); //查看目录是否已满 //为了避免同名的文本文件 for(i=1;i<BlockFcbCount;i++) { if(dir->fcb[i].type == HXSH && isFound == 0) { emptyNum = i; isFound = 1; } else if(dir->fcb[i].type==GENERAL && strcmp(dir->fcb[i].fname,name)==0 ) { printf("无法在同一目录下创建同名文件!\n"); return 0; } } if(emptyNum == 0) { printf("已经达到目录项容纳上限,无法创建新目录!\n"); return 0; } //查找FAT表寻找空白区,用来分配磁盘块号j for(i = 3;i<BlockCount;i++) { if(osPoint->FAT1[i]==0) break; } if(i==BlockCount) { printf("磁盘已满!\n"); return 0; } iFAT=i; /*------进入分配阶段---------*/ //分配磁盘块 osPoint->FAT1[iFAT] = osPoint->FAT2[iFAT] = 1; /*-----------接下来进行分配----------*/ //填写该分派新的盘块的参数 strcpy(dir->fcb[emptyNum].fname,name); dir->fcb[emptyNum].type=GENERAL; dir->fcb[emptyNum].fatherBlockNum=current; dir->fcb[emptyNum].currentBlockNum=iFAT; dir->fcb[emptyNum].size =0; char* p = osPoint->data[iFAT -3]; memset(p,4,BlockSize); printf("----------------------------------------------------------------\n\n"); return 1; } /*-------查询子目录------------*/ int listshow() { int i,DirCount=0,FileCount=0; //搜索当前目录 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i=1;i<BlockFcbCount;i++) { if(dir->fcb[i].type==GENERAL) { //查找普通文件 FileCount++; printf("%s 文本文件.\n",dir->fcb[i].fname); } if(dir->fcb[i].type==DIRECTORY) { //查找目录文件 DirCount++; printf("%s 文件夹.\n",dir->fcb[i].fname); } } printf("\n该目录下共有 %d 个文本文件, %d 个文件夹\n\n",FileCount,DirCount); printf("--------------------------------------------------------\n\n"); return 1; } /*---------在当前目录下删除文件-----------*/ int delfile(char *name) { int i,temp,j; //确保当前目录下有该文件,并且记录下它的FCB下标 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i=1;i<BlockFcbCount;i++) //查找该文件 { if(dir->fcb[i].type==GENERAL && strcmp(dir->fcb[i].fname,name)==0) { break; } } if(i==BlockFcbCount) { printf("当前目录下不存在该文件!\n"); return 0; } int k; for(k=0;k<OPEN_MAX;k++) { if((openlist->f [k].type = GENERAL)&& (strcmp(openlist->f [k].fname,name)==0)) { if(openlist->f[k].fatherBlockNum == current) { break; } else { printf("该文件未在当前目录下!\n"); return 0; } } } if(k!=OPEN_MAX) { close(name); } //从打开列表中删除 temp=i; /*开始删除文件操作*/ j = dir->fcb [temp].currentBlockNum ; //查找盘块号j osPoint->FAT1[j]=osPoint->FAT2[j]=0; //fat1,fat2表标记为空白 char *p=osPoint->data[j - 3]; memset(p,0,BlockSize); //清除原文本文件的内容 dir->fcb[temp].initialize(); //type=0; //标记该目录项为空文件 printf("------------------------------------------------------------\n\n"); return 1; } /*--------------进入当前目录下的子目录--------------*/ int changePath(char *sonfname) { struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); /*回到父目录*/ if(strcmp(sonfname,"..")==0) { if(current==2) { printf("你现已经在根目录下!\n"); return 0; } current = dir->fcb[0].fatherBlockNum ; currentPath = currentPath.substr(0,currentPath.size() - strlen(dir->fcb[0].fname )-1); return 1; } /*进入子目录*/ int i,temp; //确保当前目录下有该目录,并且记录下它的FCB下标 for(i = 1; i < BlockFcbCount; i++) { //查找该文件 if(dir->fcb[i].type==DIRECTORY && strcmp(dir->fcb[i].fname,sonfname)==0 ) { temp=i; break; } } if(i==BlockFcbCount) { printf("不存在该目录!\n"); return 0; } //修改当前文件信息 current=dir->fcb [temp].currentBlockNum ; currentPath = currentPath+dir->fcb [temp].fname +"\\"; printf("-------------------------------------------------------------\n\n"); return 1; } /*--------System exit---------------------*/ int exit() { //将所有文件都关闭 //保存到磁盘上C:\myfiles fp=fopen(FilePath,"w+"); fwrite(BaseAddr,sizeof(char),DiskSize,fp); fclose(fp); //释放内存上的虚拟磁盘 free(osPoint); //释放用户打开文件表 delete openlist; printf("---------------------------------------------------------\n\n"); return 1; } /*-------------在指定的文件里记录信息---------------*/ int write(char *name) { int i; char *startPoint,*endPoint; //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!) for(i=0;i<OPEN_MAX;i++) { if(strcmp(openlist->f [i].fname,name)==0 ) { if(openlist->f[i].fatherBlockNum ==current) { break; } else { printf("该文件处于打开列表中,本系统只能改写当前目录下文件!\n"); return 0; } } } if(i==OPEN_MAX) { printf("该文件尚未打开,请先打开后写入信息!!\n"); return 0; } int active=i; int fileStartNum = openlist->f[active].currentBlockNum - 3 ; startPoint = osPoint->data[fileStartNum]; endPoint = osPoint->data[fileStartNum + 1]; printf("请输入文本以Ctrl D号结束:\t"); char input; while(((input=getchar())!=4)) { if(startPoint < endPoint-1) { *startPoint++ = input; } else { printf("达到单体文件最大容量!"); *startPoint++ = 4; break; } } return 1; } /*---------选择一个打开文件读取信息----------*/ int read(char *file) { int i,fileStartNum; char *startPoint,*endPoint; //struct dirFile *dir; //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!) for(i=0;i<OPEN_MAX;i++) { if(strcmp(openlist->f [i].fname,file)==0 ) { if(openlist->f[i].fatherBlockNum ==current) { break; } else { printf("该文件处于打开列表中,本系统只能阅读当前目录下文件!\n"); return 0; } } } if(i==OPEN_MAX) { printf("该文件尚未打开,请先打开后读取信息!\n"); return 0; } int active=i; //计算文件物理地址 fileStartNum = openlist->f[active].currentBlockNum - 3 ; startPoint = osPoint->data[fileStartNum]; endPoint = osPoint->data[fileStartNum + 1]; //end_dir=(struct dirFile *)[BlockSize-1]; //q=(char *)end_dir; printf("该文件的内容为: "); while((*startPoint)!=4&& (startPoint < endPoint)) { putchar(*startPoint++); } printf("\n"); return 1; } /*当前目录下添加一个打开文件*/ int open(char *file)//打开文件 { int i,FcbIndex; //确保没有打开过该文件 = 相同名字 + 相同目录 for(i=0;i<OPEN_MAX;i++) { if(openlist->f[i].type ==GENERAL && strcmp(openlist->f [i].fname,file)==0 &&openlist;->f[i].fatherBlockNum == current) { printf("该文件已经被打开!\n"); return 0; } } //确保有空的打开文件项 if(openlist->files == OPEN_MAX) { printf("打开文件数目达到上限!无法再打开文件.\n"); return 0; } //确保当前目录下有该文件,并且记录下它的FCB下标 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i = 1;i< BlockFcbCount;i++) { //查找该文件 if(dir->fcb[i].type==GENERAL && strcmp(dir->fcb[i].fname,file)==0 ) { FcbIndex=i; break; } } if(i==BlockFcbCount) { printf("当前目录下不存在该文件!\n"); return 0; } //装载新文件进入打开文件列表,(FCB信息,文件数++) ??难道名字过不来? openlist->f[OpenFileCount] = dir->fcb[FcbIndex]; //FCB拷贝 openlist->files ++; printf("文件打开成功!\n"); OpenFileCount++; return 1; } int close(char *file) { //释放该文件所占内存 //释放用户打开文件列表表项 int i; //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!) for(i=0;i<OPEN_MAX;i++) { if((openlist->f [i].type = GENERAL)&& (strcmp(openlist->f [i].fname,file)==0)) { if(openlist->f[i].fatherBlockNum == current) { break; } else { printf("该文件打开,但未在当前目录下,无法关闭!\n"); return 0; } } } if(i==OPEN_MAX) { printf("该文件未在打开列表中!\n"); return 0; } int active=i; openlist->files --; openlist->f[active].initialize(); OpenFileCount--; printf("该文件已关闭!\n"); return 1; } int main() { /*********************************************************************/ printf("-----Welcome To My Operate System Of File(FAT)-----\n"); //使用说明书 printf("\n 以下是使用说明书:\n"); printf("--------------------------------------------------------------\n"); printf("|| format :对磁盘格式化. || \n"); printf("|| exit :安全退出该文件系统,保存信息. || \n"); printf("|| mkdir dirname :创建子目录. || \n"); printf("|| rmdir dirname :删除子目录. || \n"); printf("|| ls dirname :显示当前目录下信息. || \n"); printf("|| cd dirname :更改当前目录. || \n"); printf("|| create filename :创建一个新文件,并且打开. || \n"); printf("|| write filename :选择一个打开文件写入信息 || \n"); printf("|| read filename :选择一个打开文件读取信息. || \n"); printf("|| rm filename :删除文件. || \n"); printf("|| open filename :打开文件. || \n"); printf("|| close filename :关闭文件. || \n"); printf("-------------------------------------------------------------\n\n"); //创建用户文件打开表 openlist=new OPENLIST; //申请虚拟空间并且初始化 BaseAddr=(char *)malloc(DiskSize); //虚拟磁盘初始化 osPoint=(struct DISK *)(BaseAddr); //加载磁盘文件 if((fp=fopen(FilePath,"r"))!=NULL){ fread(BaseAddr,sizeof(char),DiskSize,fp); printf("加载磁盘文件( %s )成功,现在可以进行操作了!\n\n",FilePath); } else{ printf("这是你第一次使用该文件管理系统!\t正在初始化...\n"); format(); printf("初始化已经完成,现在可以进行操作了!\n\n"); } printf("--------------------------------------------------------------\n\n"); while(1){ cout<<currentPath; cin>>cmd; if(cmd=="format"){ format(); } else if(cmd=="mkdir"){ cin>>command; mkdir(command); } else if(cmd=="rmdir"){ cin>>command; rmdir(command); } else if(cmd=="ls"){ listshow(); } else if(cmd=="cd"){ cin>>command; changePath(command); } else if(cmd=="create"){ cin>>command; create(command); } else if(cmd=="write"){ cin>>command; write(command); } else if(cmd=="read"){ cin>>command; read(command); } else if(cmd=="rm"){ cin>>command; delfile(command); } else if(cmd=="open"){ cin>>command; open(command); } else if(cmd=="close"){ cin>>command; close(command); } else if(cmd=="exit"){ exit(); break; } else cout<<"无效指令,请重新输入:"<<endl; } printf("Thank you for using my file system!\n"); return 0; }
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一键难忘

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

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

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

打赏作者

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

抵扣说明:

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

余额充值