为了账号安全,请及时绑定邮箱和手机立即绑定

正在进行I / O删除文件:它是文件系统和/或OS功能吗?

正在进行I / O删除文件:它是文件系统和/或OS功能吗?

杨__羊羊 2021-04-09 15:15:04
我正在编写将在Linux上运行但可以对已安装分区上的文件进行操作的shell脚本,可能有也可能没有ext *文件系统。例如,它可以是NTFS,FAT32或任何基于inode或基于非inode的系统;可以进一步将其重新安装在其他运行非Linux操作系统(例如Windows或Mac)的机器上。此外,我的脚本需要能够通过在Linux,Windows或Mac机器上运行的远程进程删除此共享的,任意格式的分区上的文件(即使正在读取或写入文件时)。问题:能够删除正在使用的文件的功能,一种。仅文件系统?b。还是只有操作系统?C。还是两者的结合?(问题1的扩展)在文件上执行I / O和删除文件的进程是本地的还是远程的,这有关系吗?
查看完整描述

2 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

在文件上执行I / O和删除文件的I / O进程是本地的还是远程的,这有关系吗?


有趣的是-远程系统如何直接在Windows上访问文件(打开,读写数据,删除)?真的,这不可能。我们需要一些在本地系统中运行的代理(LANMan服务器),该代理将通过远程命令(由Network Redirector发送)对文件进行本地操作。因此,从文件系统视图来看-所有操作始终是本地的。


能够删除正在使用的文件的功能


这当然是由文件系统驱动程序实现的,但是该驱动程序是为具体OS编写的,并基于该规则。磁盘上的文件系统数据具有通用格式(因此,驱动器在一个OS中格式化(和写入的文件),可以从另一OS读取)-文件系统驱动程序如何处理请求,打开,读取,写入,删除文件-这是特定于操作系统。针对不同的操作系统而有所不同。根据它的规则。因此磁盘上的数据格式是常见的,并且仅取决于文件系统。但是如何读取/写入/删除此数据-已经特定于操作系统。


在Windows中,我们有删除文件的下一条规则:


通常,只有在关闭了该文件的所有打开句柄并且该文件的链接计数为零时,才会真正删除标记为删除的文件。当使用FILE_DISPOSITION_POSIX_SEMANTICS将文件标记为删除时 ,只要POSIX删除句柄已关闭,该链接就会从可见的命名空间中删除,但是其他现有句柄仍可访问该文件的数据流,直到最后一个句柄已关闭。


因此,一般来说,文件不会被删除,直到关闭文件的最后一个句柄为止。尝试删除文件后无法访问该文件-无法再将其打开(我们收到错误消息,请求对具有待处理删除操作的文件对象执行非关闭操作。如果尝试这样做,请在标记为删除的文件之后进行)。但是如果文件已经打开-我们仍然可以通过此句柄使用它。如果文件上存在节,也无法删除文件-将是错误试图删除无法删除的文件或目录。


从win10开始redstone1 build existFILE_DISPOSITION_POSIX_SEMANTICS标志,当删除句柄关闭时,该文件允许从可见的命名空间中删除文件名,但是其他现有句柄仍可访问文件的数据流,直到最后一个句柄关闭为止


Windows代码测试演示:(FILE_DISPOSITION_POSIX_SEMANTICS由ntfs支持仅从开始_WIN32_WINNT_WIN10_RS1。FileDispositionInfoEx信息类也_WIN32_WINNT_WIN10_RS1仅从支持开始。在以前的构建中,我们只是未实现错误)


void print_error(PCSTR name)

{

    PWSTR sz;

    NTSTATUS status = RtlGetLastNtStatus();

    if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE, 

        GetModuleHandle(L"ntdll"), status, 0, (PWSTR)&sz, 0, 0))

    {

        DbgPrint("%s=%x\n%S\n", name, status, sz);

        LocalFree(sz);

    }

}


HANDLE OpenFile(PCWSTR lpFileName, DWORD dwDesiredAccess)

{

    HANDLE hFile = CreateFileW(lpFileName, dwDesiredAccess, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);


    if (hFile == INVALID_HANDLE_VALUE)

    {

        print_error("OpenFile");

        return 0;

    }


    return hFile;

}


void ReadTest(HANDLE hFile)

{

    if (hFile)

    {

        ULONG dwBytes;

        if (ReadFile(hFile, &dwBytes, sizeof(dwBytes), &dwBytes, 0))

        {

            DbgPrint("ReadFile=OK\n");

        }

        else

        {

            print_error("ReadFile");

        }

    }

}


void DeleteTest(PCWSTR lpFileName)

{

    HANDLE hFile1, hFile2, hFile3;


    if (hFile1 = OpenFile(lpFileName, DELETE))

    {

        hFile2 = OpenFile(lpFileName, FILE_GENERIC_READ);


        FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS };

        if (!SetFileInformationByHandle(hFile1, FileDispositionInfoEx, &fdi, sizeof(fdi)))

        {

            print_error("SetFileInformationByHandle");

        }


        // file already not accessible here (open must fail) but visible

        if (hFile3 = OpenFile(lpFileName, FILE_GENERIC_READ))

        {

            CloseHandle(hFile3);

        }


        ReadTest(hFile2);


        // win10 rs1: file removed from the visible namespace here

        CloseHandle(hFile1);


        // are file still visible ?

        if (hFile3 = OpenFile(lpFileName, FILE_GENERIC_READ))

        {

            CloseHandle(hFile3);

        }


        // are possible create new file with this name &

        hFile3 = CreateFileW(lpFileName, DELETE, 

            FILE_SHARE_VALID_FLAGS, 0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);

        if (hFile3 == INVALID_HANDLE_VALUE)

        {

            print_error("CreateFile");

        }

        else

        {

            CloseHandle(hFile3);

            DbgPrint("CreateFile OK\n");

        }


        ReadTest(hFile2);


        if (hFile2)

        {

            CloseHandle(hFile2);

        }

    }

}

和输出


OpenFile=c0000056

A non close operation has been requested of a file object with a delete pending.


ReadFile=OK

OpenFile=c0000034

Object Name not found.


CreateFile OK

ReadFile=OK


查看完整回答
反对 回复 2021-04-16
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

这取决于您如何定义文件系统和操作系统。通常,我了解在文件系统下数据存储在设备上的组织方式。然后,操作系统负责数据和文件的I / O。特别是,如果您的脚本想要删除文件,它将调用rm之类的实用程序并提供文件名。该实用程序是一个进行适当的系统调用的程序。该系统调用是在特权模式下执行的操作系统的一部分。它实现了什么以及如何做(例如,应该使用哪些驱动程序将HDD块标记为在特定驱动器上为空闲,或者应该调用某些远程过程或涉及到samba服务器等。)因此,请回答您的问题1,我倾向于答案b。


查看完整回答
反对 回复 2021-04-16
  • 2 回答
  • 0 关注
  • 332 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信