Java如何删除设置了不可变位的文件

Java如何删除设置了不可变位的文件,java,Java,在Java8项目中,我从外部源复制文件。在其中一个源中,文件设置为不可变位标志 在OSX中这样设置 sudo chflags schg /path/to/file 在Linux中 chattr +i /path/to/file 我现在需要删除已复制的文件。我一直在使用Apache Commons IO来删除目录,就像这样 FileUtils.deleteDirectory(new File("/path/here")); 但是,这会导致java.io.IOException崩溃 是否有跨平

在Java8项目中,我从外部源复制文件。在其中一个源中,文件设置为不可变位标志

在OSX中这样设置

sudo chflags schg /path/to/file
在Linux中

chattr +i /path/to/file
我现在需要删除已复制的文件。我一直在使用Apache Commons IO来删除目录,就像这样

FileUtils.deleteDirectory(new File("/path/here"));
但是,这会导致
java.io.IOException
崩溃

是否有跨平台的方式删除这些文件?正在运行的进程是文件的所有者

有没有跨平台的方式来删除这些文件

不是我能找到的。我不得不采用你已经考虑过的显而易见的解决方案,这是一个漫长的过程:

  • 检测我正在运行的操作系统
  • 发出相应的shell命令以删除不可变位
  • 确认它已被删除
  • 最后删除(在我的例子中,更改)文件
实际上,更简单、更懒惰的捷径是:

private static String OS = System.getProperty("os.name").toLowerCase();
if(OS.indexOf("win") >= 0)
    //your code for windows OS.
else if(OS.indexOf("mac") >= 0)
    //your code for MAC OS.
else if(OS.indexOf("sunos") >= 0)
    //your code for Solaris OS
  • 对所有已知二进制文件(
    /usr/bin/chattr
    等)盲目执行解锁命令,使用完整路径避免可能的安全问题。他们很快就会失败,只有一个例外;例如,在Linux上,对
    ATTRIB.EXE
    chflags
    的任何调用都将失败。如果全部失败,则系统不受支持
  • 使用适当的参数执行一个未失败的二进制文件,或相应的检查二进制文件(例如,
    lsattr
    for
    chattr
    ),以验证标志的删除
  • 或者您可以尝试删除该文件,然后捕获
    java.io.IOException
我开始研究
chattr
做了什么,但很明显,我需要发出几个专门的、特定于操作系统的系统调用:因此,调用外部二进制文件没有什么真正的优势,也许除了性能,但在我的例子中这不是问题

一旦你走上了特定于操作系统(本机)的道路,无论是通过JNI还是在Linux系统上,调用

请注意,仅识别操作系统是不够的,您还需要识别文件系统,因为在例如FAT32文件系统或NTFS-3G FSs上,IOCTL将返回错误(该标志在低级别不可用,或者IOSS中间驱动程序(尚未)支持)

在中也存在同样的问题,在高级别上提供了一个与操作系统无关的调用。。。但它并不适用于任何地方。

问题:因为,我们知道设置了不可变属性的文件不能被任何用户删除。即使根用户也无法删除以下文件。

现在,要删除该文件,必须删除不可变属性,然后删除该文件。

现在,您要做的是通过代码应用shell命令并删除文件上的不可变属性。

正如您提到的跨平台问题

所以基本算法是

步骤1:检测您正在使用的操作系统示例代码为:

private static String OS = System.getProperty("os.name").toLowerCase();
if(OS.indexOf("win") >= 0)
    //your code for windows OS.
else if(OS.indexOf("mac") >= 0)
    //your code for MAC OS.
else if(OS.indexOf("sunos") >= 0)
    //your code for Solaris OS
注意:我没有添加检查所有操作系统的代码。因此,您可以自己看一看。
步骤2:此步骤帮助您解决跨平台问题
通过
java.lang.Runtime.exec
发出相应的shell命令以删除文件的不可变属性
看这张照片。
java.lang.Runtime.exec:通过该命令,您可以为任何底层环境(无论是MAC、Windows、Linux等)提供适当的shell命令

示例代码为

注意:要运行包含管道的其他shell命令,可以使用以下示例代码:

Process p = Runtime.getRuntime().exec(new String[]{"csh","-c","cat /home/narek/pk.txt"});

步骤3:使用相同的Runtime.exec()检查不可变属性是否已删除,如下所示:

Process p = Runtime.getRuntime().exec("lsattr /whateverPath");
//Play with the process to check whether the attribute is set or not, using the documentation.

步骤4:如果步骤3为true | false,则无论应用何种逻辑,然后使用Runtime.exec()再次使用相应的命令删除该文件

事情是看一看上面链接的java.lang.Runtime.exec文档并使用它。

请告诉我它是否有一定的帮助。

您是否尝试过查看
java.nio.file.attribute
中的类
chattr
是非常特定于Linux的,它的一些参数是特定于文件系统的,所以我怀疑Java是否绑定到它。通过shell命令提供您自己的实现可能更安全。是的,我看过了。我确实考虑过剥壳,但我想有一个跨平台的方法来处理这个问题,而不是必须在多个平台上实现Linux /BSD/Windows层。只是我的意见,不确定它是否适用于这里,但是我将避免处理java中如此低的东西。我的建议是使用相关的OS命令(或shell)。例如,使用
chflags
将是
chflags-r0/path/here
。然后您可以使用可移植的java代码…不确定,但java nio2文件属性会有帮助吗?看看这个项目:neat sol,我只建议在复制文件后立即执行
unset
命令,所以剩下的步骤是:处理和删除。。。光滑的;)那很酷。我在想该怎么评论,但后来觉得你的评论更酷p@Yazan