gpt4 book ai didi

Java删除文件unix方式(unlink header)

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:11:55 26 4
gpt4 key购买 nike

我遇到一个问题,如果在清理期间由网络用户打开,用 Java 编写的存档模块无法清理通过 smb 共享的文件。以下是文件清理代码的简化版本:

    private static boolean moveFile(String sourceFilePath, String targetFilePath) {

boolean fileStatus = false;
File sourceFile = new File(sourceFilePath );
File targetFile = new File(targetFilePath );
if(sourceFile.canRead() && sourceFile.canWrite() ) {
if(targetFile.exists()) {
fileStatus = (new File(targetFilePath)).delete();
if(!fileStatus) {
Logger.ERROR("Target deletion failed");
}
}

fileStatus = sourceFile.renameTo(new File(targetFilePath));

if(!fileStatus) {
Logger.ERROR("RenameTo method failed");
return false;
} else {
Logger.INFO("Move succeeded");
return true;
}
} else {
Logger.ERROR("Cannot read file");
return false;
}
}

当我在两个 Linux session 中测试它时,它工作正常: session A:

cat -v /dev/zero > sourceFile.txt

session B:

java -jar JavaUnixFileRemovalTest.jar sourceFile.txt targetFile.txt

但在使用网络共享和用户时在生产中失败。

我想要实现的是将文件复制到存档文件夹并取消链接 header 。这样,如果用户仍然打开文件,他将继续访问内容,同时从文件系统中删除名称,这样其他人就无法看到该文件。

所以问题是,是否有一种方法可以通过 native Java 在 Unix 中取消链接文件头,而无需显式调用 unlink 命令

最佳答案

经过一番研究后,我决定以一种有点不同的方式解决这个问题,并施展强大的远古遗迹魔法——也就是说,在 JNA (Java Native Access) 的帮助下使用 native 系统 C 调用。

下面是一个代码示例,其中包含一些针对 JNA 初学者的解释:

package com.WeLoveStackOverflow.JavaJNAUnlinkTest;

import java.io.File;
import com.sun.jna.Library;
import com.sun.jna.Native;

public class Main {
private static CStdLib cStdLib;

// Here you specify prototypes of native C methods to be called during runtime
// Because unlink(char *path) uses pointer to const char as argument, a wrapper class StringByReference is used to convert data types
// Link to other examples at the end of this post
public interface CStdLib extends Library {
int unlink(StringByReference path);
}

public static void main(String[] args) {

// Here I'm declaring libc usage, but you can link anything. Even your own libraries
cStdLib = (CStdLib)Native.loadLibrary("c", CStdLib.class);

Logger.INFO("Source file: " + args[0]);
Logger.INFO("Target file: " + args[1]);
moveFile(args[0],args[1]);
}

private static boolean moveFile(String sourceFilePath, String targetFilePath) {
boolean fileStatus = false;
File sourceFile = new File(sourceFilePath );
File targetFile = new File(targetFilePath );
if(sourceFile.canRead() && sourceFile.canWrite() ) {
if(targetFile.exists()) {
fileStatus = targetFile.delete();
if(!fileStatus) {
Logger.ERROR("Target deletion failed");
}
}

fileStatus = sourceFile.renameTo(targetFile);

if(!fileStatus) {
Logger.ERROR("RenameTo method failed");
Logger.INFO("Trying to copy file and unlink the original");

// ToDo: add copy method

// That's where we convert String to char*
StringByReference unlinkPath=new StringByReference(sourceFilePath);
int status=cStdLib.unlink(unlinkPath);

if(status==0){
Logger.INFO("Unlink succeeded");
}else {
Logger.ERROR("Unlink also failed");
return false;
}
} else {
Logger.INFO("Move succeeded");
}
} else {
Logger.ERROR("Cannot read file");
return false;
}
return true;
}
}

以及用于转换数据类型的类:

package com.WeLoveStackOverflow.JavaJNAUnlinkTest;
import com.sun.jna.ptr.ByReference;

public class StringByReference extends ByReference {
public StringByReference() {
this(0);
}

public StringByReference(String str) {
super(str.length() < 4 ? 4 : str.length() + 1);
setValue(str);
}

private void setValue(String str) {
getPointer().setString(0, str);
}
}

那么我们最终得到了什么?一个不错的 Java 取消链接实用程序!测试场景:在 session A 中创建一个文本文件,在 session B 中用 less 打开它并在 session A 中运行 java 代码。按预期工作:

[me@server1 JavaFileTest]$ lsof | grep sourceFile
less 12611 me 4r REG 253,0 0 73 /home/me/JavaFileTest/sourceFile (deleted)

这是我用作引用的文章: http://jnaexamples.blogspot.com/2012/03/java-native-access-is-easy-way-to.html它包含其他为 C 调用包装数据类型的好例子

提示:

  • 确保类路径中同时包含 JNA 和 JNA 平台文件
  • JNA 4.4.0 需要 GLIBC_2.14。如果你收到这个错误只需降级 JNA(4.2.2 对我有用)

    线程“主”java.lang.UnsatisfiedLinkError 中的异常:/lib64/libc.so.6:找不到版本“GLIBC_2.14”

关于Java删除文件unix方式(unlink header),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43342059/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com