怎么实时读取更新中的文件但是不影响其他程序重命名或者删除?

工作所需,需要写一个程序读取一直在更新的log文件(Wintrace.log),发现里面的error。 同时有另外的程序写入log文件,在log文件的大小达到15626kb时改名字(wintrace-001.log),并且重新生成一个空的log文件(Wintrace.log)。

第一种方法:直接打开原文件Wintrace.log。

fo = open("C:\Winusr\Wintrace.log", "rb")

发现我的程序不会阻止其他的程序写入,但是会阻止log file在满的时候改名字。导致log file丢失的问题。因为如果无法重命名,他就只能在现在的log file清除重新写入,历史文件将不存在。 

第二种方法:实时复制原文件。读取复制的文件。

old_size = os.path.getsize("C:\Winusr\Wintrace.log")
while os.path.getsize("C:\Winusr\Wintrace.log")>= old_size:
    shutil.copy("C:\Winusr\Wintrace.log", "C:\Winusr\wintrace1.log")
    fo = open("C:\Winusr\wintrace1.log", "rb")

发现还是不可以。虽然copy的操作看起来没有影响到原文件,但是copy操作是逐字节copy,实际上已经打开了原文件。所以还是行不通,无法重命名。

第三种方法:使用popen copy原文件。

os.chdir("C:\Winusr")
original_path = paths["wintrace"][10:]
if original_path == "Wintrace.log":
    f = os.popen('copy Wintrace.log wintrace1.log')
    f.close()
fo = open("C:\Winusr\wintrace1.log", "rb")

网上说是打开了一个子程序,不会影响主程序。但是我不懂。试过了之后发现可以重命名。但是目前好像又发现一个问题,还不确定。就是在log file快要到达15626KB时,主程序出现了报错?

 

各位大佬有什么建议吗?

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1/12/2021

终于找到了一个目前看来还没什么问题的解决方案。

早知道第一次就用这个办法了,也不至于搞死其他程序。。。

用的是win32file。

程序如下:

import win32file

file_handle = win32file.CreateFile(paths["wintrace"], win32file.GENERIC_READ,
win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL, None)

win32file.SetFilePointer(file_handle, 1, start_point)
result, fo = win32file.ReadFile(file_handle, 100000000)
for line in fo.splitlines():
    line = str(line.decode('ISO-8859-1'))
    print(line)
start_point = win32file.FILE_END            
win32file.CloseHandle(file_handle)

要注意的问题:

1. 安装win32file需要安装pywin32而不是直接安装win32file(对我来说)。直接“pip install win32file”会报错。“pip install pywin32” 则可以安装成功。

2. win32file.CreateFile 返回的是句柄而不是文件类型,所以不可以直接用open打开。打开它需要用win32file.Readfile(). 如果需要逐行读取,则需要用到splitlines.

3. 关于文件指针,需要用

win32file.SetFilePointer(file_handle, 1, start_point)
start_point = win32file.FILE_END(用来获取文件最后的位置)

4. 记得用完之后关闭句柄:

win32file.CloseHandle(file_handle)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
为了实现一个简单的文件系统,需要考虑以下几个方面: 1. 文件系统的结构 2. 文件的存储方式 3. 文件的读写操作 4. 文件的管理操作 下面是一个简单的文件系统的实现,实现了上述要求的功能。 1. 文件系统的结构 为了实现一个简单的文件系统,我们可以使用一个类似于 FAT 文件系统的结构。使用一个文件系统控制块(File System Control Block,简称 FSCB)来存储整个文件系统的信息,包括文件系统的大小、空闲块的链表、以及文件的目录等信息。 文件系统的每个文件可以使用一个文件控制块(File Control Block,简称 FCB)来描述,包括文件名、文件大小、文件的起始块号等信息。 2. 文件的存储方式 在文件系统,我们可以将文件分成若干个大小相等的块来存储,每个块的大小可以根据具体情况来设置。在本例,我们将每个块的大小设置为 512 字节。 为了方便起见,我们使用了一个简单的数据结构来描述文件系统的块,包括块号、块的大小、块的内容等信息。 3. 文件的读写操作 在文件系统,我们可以使用文件的起始块号和文件的大小来定位文件在磁盘的位置,然后读取或写入文件的内容。 4. 文件的管理操作 在文件系统,我们可以实现以下的文件管理操作: - 文件创建:在文件系统创建一个新文件,并分配空间存储其内容。 - 文件解密:对加密的文件进行解密,使其可读。 - 文件显示:将文件的内容显示在屏幕上。 - 文件列目录:列出文件系统的所有文件。 - 文件删除删除文件,并释放其占用的空间。 - 文件加密:对文件进行加密,使其不可读。 - 文件合并:将多个文件合并成一个文件。 - 文件查询:查询文件是否存在,并返回文件的信息。 - 文件复制:复制一个文件到另一个位置。 - 文件重命名:将文件重命名为一个新的名称。 下面是一个简单的 C 语言程序,实现了上述的文件系统功能。该程序使用了一个文件系统控制块(fs)来描述整个文件系统,以及一个文件控制块(fcb)来描述每个文件文件系统的每个块使用一个结构体(block)来描述,包括块号、块的大小以及块的内容等信息。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define BLOCK_SIZE 512 // 块的大小 #define MAX_FILENAME_LENGTH 64 // 文件名的最大长度 #define MAX_FILE_COUNT 1024 // 最大文件数 #define MAX_BLOCK_COUNT 1024 // 最大块数 // 文件控制块 typedef struct { char name[MAX_FILENAME_LENGTH]; // 文件名 int size; // 文件大小 int start_block; // 文件起始块号 int is_encrypted; // 是否加密 } fcb; // 块 typedef struct { int block_no; // 块号 int size; // 块大小 char data[BLOCK_SIZE]; // 块内容 } block; // 文件系统控制块 typedef struct { int block_count; // 块数 int free_block; // 空闲块链表头 int file_count; // 文件数 fcb files[MAX_FILE_COUNT]; // 文件目录 block blocks[MAX_BLOCK_COUNT]; // 块 } fs; // 初始化文件系统 void init_file_system(fs* fs) { fs->block_count = MAX_BLOCK_COUNT; fs->free_block = 0; fs->file_count = 0; memset(fs->files, 0, sizeof(fs->files)); memset(fs->blocks, 0, sizeof(fs->blocks)); for (int i = 0; i < MAX_BLOCK_COUNT - 1; i++) { fs->blocks[i].block_no = i; fs->blocks[i].size = BLOCK_SIZE; fs->blocks[i].data[0] = '\0'; fs->blocks[i].data[1] = i + 1; } fs->blocks[MAX_BLOCK_COUNT - 1].block_no = MAX_BLOCK_COUNT - 1; fs->blocks[MAX_BLOCK_COUNT - 1].size = BLOCK_SIZE; fs->blocks[MAX_BLOCK_COUNT - 1].data[0] = '\0'; fs->blocks[MAX_BLOCK_COUNT - 1].data[1] = -1; } // 在文件系统查找一个空闲块 int find_free_block(fs* fs) { if (fs->free_block < 0) { return -1; } int block_no = fs->free_block; fs->free_block = fs->blocks[block_no].data[1]; return block_no; } // 将一个块设置为空闲块 void free_block(fs* fs, int block_no) { fs->blocks[block_no].data[1] = fs->free_block; fs->free_block = block_no; } // 在文件系统查找一个文件 int find_file(fs* fs, const char* name) { for (int i = 0; i < fs->file_count; i++) { if (strcmp(fs->files[i].name, name) == 0) { return i; } } return -1; } // 创建文件 void create_file(fs* fs, const char* name, int size) { if (fs->file_count >= MAX_FILE_COUNT) { printf("File system is full!\n"); return; } if (size <= 0) { printf("Invalid file size!\n"); return; } if (find_file(fs, name) >= 0) { printf("File already exists!\n"); return; } int block_count = (size + BLOCK_SIZE - 1) / BLOCK_SIZE; int start_block = find_free_block(fs); if (start_block < 0) { printf("No free blocks!\n"); return; } fs->files[fs->file_count].size = size; fs->files[fs->file_count].start_block = start_block; fs->files[fs->file_count].is_encrypted = 0; strncpy(fs->files[fs->file_count].name, name, MAX_FILENAME_LENGTH - 1); fs->files[fs->file_count].name[MAX_FILENAME_LENGTH - 1] = '\0'; fs->file_count++; for (int i = 0; i < block_count; i++) { int block_no = find_free_block(fs); if (block_no < 0) { printf("No free blocks!\n"); return; } fs->blocks[start_block + i].data[1] = block_no; } } // 解密文件 void decrypt_file(fs* fs, const char* name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } if (!fs->files[index].is_encrypted) { printf("File is not encrypted!\n"); return; } int block_count = (fs->files[index].size + BLOCK_SIZE - 1) / BLOCK_SIZE; int block_no = fs->files[index].start_block; for (int i = 0; i < block_count; i++) { for (int j = 0; j < BLOCK_SIZE; j++) { fs->blocks[block_no + i].data[j] ^= 0xff; // 异或操作来解密 } } fs->files[index].is_encrypted = 0; } // 显示文件 void show_file(fs* fs, const char* name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } int block_count = (fs->files[index].size + BLOCK_SIZE - 1) / BLOCK_SIZE; int block_no = fs->files[index].start_block; for (int i = 0; i < block_count; i++) { printf("%s", fs->blocks[block_no + i].data); } } // 列出文件系统的所有文件 void list_files(fs* fs) { printf("Name\tSize\tStart Block\n"); for (int i = 0; i < fs->file_count; i++) { printf("%s\t%d\t%d\n", fs->files[i].name, fs->files[i].size, fs->files[i].start_block); } } // 删除文件 void delete_file(fs* fs, const char* name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } int block_count = (fs->files[index].size + BLOCK_SIZE - 1) / BLOCK_SIZE; int block_no = fs->files[index].start_block; for (int i = 0; i < block_count; i++) { free_block(fs, block_no + i); } for (int i = index; i < fs->file_count - 1; i++) { fs->files[i] = fs->files[i + 1]; } fs->file_count--; } // 加密文件 void encrypt_file(fs* fs, const char* name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } if (fs->files[index].is_encrypted) { printf("File is already encrypted!\n"); return; } int block_count = (fs->files[index].size + BLOCK_SIZE - 1) / BLOCK_SIZE; int block_no = fs->files[index].start_block; for (int i = 0; i < block_count; i++) { for (int j = 0; j < BLOCK_SIZE; j++) { fs->blocks[block_no + i].data[j] ^= 0xff; // 异或操作来加密 } } fs->files[index].is_encrypted = 1; } // 合并文件 void merge_files(fs* fs, const char* name, const char* name1, const char* name2) { int index1 = find_file(fs, name1); if (index1 < 0) { printf("File not found!\n"); return; } int index2 = find_file(fs, name2); if (index2 < 0) { printf("File not found!\n"); return; } int size = fs->files[index1].size + fs->files[index2].size; create_file(fs, name, size); int block_count = (fs->files[index1].size + BLOCK_SIZE - 1) / BLOCK_SIZE; int block_no = fs->files[index1].start_block; for (int i = 0; i < block_count; i++) { int block_no1 = find_free_block(fs); if (block_no1 < 0) { printf("No free blocks!\n"); return; } memcpy(fs->blocks[block_no1].data, fs->blocks[block_no + i].data, BLOCK_SIZE); int block_no2 = find_free_block(fs); if (block_no2 < 0) { printf("No free blocks!\n"); return; } fs->blocks[block_no1].data[1] = block_no2; block_no = block_no2; } block_count = (fs->files[index2].size + BLOCK_SIZE - 1) / BLOCK_SIZE; block_no = fs->files[index2].start_block; for (int i = 0; i < block_count; i++) { int block_no1 = find_free_block(fs); if (block_no1 < 0) { printf("No free blocks!\n"); return; } memcpy(fs->blocks[block_no1].data, fs->blocks[block_no + i].data, BLOCK_SIZE); int block_no2 = find_free_block(fs); if (block_no2 < 0) { printf("No free blocks!\n"); return; } fs->blocks[block_no1].data[1] = block_no2; block_no = block_no2; } delete_file(fs, name1); delete_file(fs, name2); } // 查询文件 void query_file(fs* fs, const char* name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } printf("Name: %s\nSize: %d\nStart Block: %d\nEncrypted: %s\n", fs->files[index].name, fs->files[index].size, fs->files[index].start_block, fs->files[index].is_encrypted ? "yes" : "no"); } // 复制文件 void copy_file(fs* fs, const char* name, const char* new_name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } create_file(fs, new_name, fs->files[index].size); int block_count = (fs->files[index].size + BLOCK_SIZE - 1) / BLOCK_SIZE; int block_no = fs->files[index].start_block; for (int i = 0; i < block_count; i++) { int block_no1 = find_free_block(fs); if (block_no1 < 0) { printf("No free blocks!\n"); return; } memcpy(fs->blocks[block_no1].data, fs->blocks[block_no + i].data, BLOCK_SIZE); int block_no2 = find_free_block(fs); if (block_no2 < 0) { printf("No free blocks!\n"); return; } fs->blocks[block_no1].data[1] = block_no2; block_no = block_no2; } } // 重命名文件 void rename_file(fs* fs, const char* name, const char* new_name) { int index = find_file(fs, name); if (index < 0) { printf("File not found!\n"); return; } if (find_file(fs, new_name) >= 0) { printf("File already exists!\n"); return; } strncpy(fs->files[index].name, new_name, MAX_FILENAME_LENGTH - 1); fs->files[index].name[MAX_FILENAME_LENGTH - 1] = '\0'; } int main() { fs fs; init_file_system(&fs); create_file(&fs, "file1", 1024); encrypt_file(&fs, "file1"); show_file(&fs, "file1"); decrypt_file(&fs, "file1"); show_file(&fs, "file1"); list_files(&fs); delete_file(&fs, "file1"); create_file(&fs, "file2", 1024); create_file(&fs, "file3", 2048); merge_files(&fs, "file4", "file2", "file3"); query_file(&fs, "file4"); copy_file(&fs, "file4", "file5"); rename_file(&fs, "file4", "file6"); list_files(&fs); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

儒雅的晴天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值