慢慢欣赏linux 截断文件

本文深入探讨了在Linux系统中使用echo与truncate命令截断文件的两种方式,详细解析了其内核态行为及调用流程,为理解Linux文件操作提供了一线视角。

echo > /root/test.txt和truncate -s 0 /test.txt都可以截断文件。
如果文件句柄没有被关闭,仍然被别的进程占据写的话可以将文件的前半部分变成空洞。

前者在内核态行为是通过sys_open调用下来的

ret_from_syscall
	=>asmlinkage long sys_open(const char __user *filename, int flags, int mode);
		struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
			=>struct file *do_filp_open(int dfd, const char *pathname, int open_flag, int mode, int acc_mode)
				filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
					=>static struct file *do_last(struct nameidata *nd, struct path *path, int open_flag, int acc_mode, int mode, const char *pathname)
						filp = finish_open(nd, open_flag, acc_mode);
							=>static struct file *finish_open(struct nameidata *nd, int open_flag, int acc_mode)
								will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
								if (will_truncate)
									error = handle_truncate(&nd->path);
										=>static int handle_truncate(struct path *path)
											do_truncate(path->dentry, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, NULL);

后者是如下调用                                            

ret_from_syscall
	=>static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
		do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
			=>int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp)
				struct iattr newattrs;
				newattrs.ia_size = length;
				ret = notify_change(dentry, &newattrs);
					=>int notify_change(struct dentry * dentry, struct iattr * attr)
						error = inode_setattr(inode, attr);
							=>int inode_setattr(struct inode * inode, struct iattr * attr)
								int error = vmtruncate(inode, attr->ia_size);
									=>int vmtruncate(struct inode *inode, loff_t offset)
										error = inode_newsize_ok(inode, offset);
										oldsize = inode->i_size;
										i_size_write(inode, offset);
											=>static inline void i_size_write(struct inode *inode, loff_t i_size)
												inode->i_size = i_size;
										truncate_pagecache(inode, oldsize, offset);
										inode->i_op->truncate(inode);
								mark_inode_dirty(inode);


        
linux系统编程:用truncate调整文件大小
https://www.cnblogs.com/ghostwu/archive/2018/01/11/8269220.html

### 文件截断的方法与命令 在 Linux 系统中,可以通过系统调用和命令行工具实现文件截断操作。文件截断是指将文件的内容截断为指定的大小,若文件长度小于指定大小,则会扩展文件并填充空字符(ASCII NUL);若大于指定大小,则会丢弃超出部分的数据。 #### 使用 `ftruncate()` 和 `truncate()` 系统调用 在程序中可以通过 `ftruncate()` 和 `truncate()` 实现文件截断操作。`ftruncate()` 需要传入一个已打开的文件描述符,而 `truncate()` 则直接接受文件路径作为参数。例如,使用 `open()` 打开文件后,调用 `ftruncate()` 将文件截断0 长度;使用 `truncate()` 将文件截断为 1024 字节长度 [^1]。 示例代码如下: ```c #include <fcntl.h> #include <unistd.h> int main() { int fd = open("file1", O_WRONLY | O_CREAT, 0666); ftruncate(fd, 0); // 将文件 file1 截断0 字节 close(fd); truncate("file2", 1024); // 将文件 file2 截断为 1024 字节长度 return 0; } ``` #### 使用 `truncate` 命令 在命令行中可以使用 `truncate` 命令实现文件截断。常用选项包括: - `-s, --size=SIZE`:指定文件的新大小,单位为字节。如果文件当前的大小比指定的大小小,则文件会被扩展到指定的大小;如果文件当前的大小比指定的大小大,则文件会被截断为指定的大小。 - `-c, --no-create`:如果文件不存在,则不创建新文件- `-o, --io-blocks`:以块为单位指定文件的大小。 例如,将文件 `example.txt` 截断为 1MB 的大小: ```bash truncate -s 1M example.txt ``` 该命令将文件 `example.txt` 的大小设置为 1MB,如果文件内容不足 1MB,则会扩展并填充空字符;如果超过,则会截断多余部分 [^2]。 #### 使用 `dd` 命令结合 `/dev/zero` 除了直接截断文件外,还可以使用 `dd` 命令结合 `/dev/zero` 设备文件创建一个全为 0文件。例如,创建一个大小为 10MB 的文件: ```bash dd if=/dev/zero of=output_file bs=1M count=10 ``` 该命令将从 `/dev/zero` 读取空字符,并写入 `output_file` 文件中,最终生成一个 10MB 大小的全零文件 [^3]。 #### 使用 `cp` 命令复制并截断文件 在使用 `cp` 命令复制文件时,目标文件若已存在,默认会覆盖并截断为源文件的大小。例如: ```bash cp source_file target_file ``` 若 `target_file` 已存在,则其内容会被截断并替换为 `source_file` 的内容。若需要保留原有内容,则应使用 `-a` 或 `-f` 等选项控制行为 [^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值