Java renameto无效,Java File.renameTo(文件)不起作用

I'm trying to list a directory's contents, and rename certain files.

public void run(String dirName) {

try {

File parDir = new File(dirName);

File[] dirContents = parDir.listFiles();

// Rename if necessary

for(File f : dirContents) {

System.out.println("f is:\n" + f.toString());

String name = f.getName();

String subbedName = name.replaceAll("\uFFFD", "_");

System.out.println("\n" + "name = " + name + ", subbedName = " + subbedName + "\n");

if(!name.equals(subbedName)) {

File newFile = new File(f.getParentFile(), subbedName);

System.out.println("newFile is:\n" + newFile.toString());

if(!f.renameTo(newFile))

System.out.println("Tried to change file name but couldn't.");

}

}

}

catch(Exception exc1) {

System.out.println("Something happened while listing and renaming directory contents: " + exc1.getMessage());

}

}

When I run this, I get "Tried to change file name but couldn't." I don't believe that Java is considering these files to be "open", so I don't think that's the reason. I've even ran chmod 777 myDir where myDir is the value of the dirName string passed into the run method.

What am I missing here? Why won't Java rename these file(s)? These are CentOS machines.

Edit: Added printouts for both f and newFile, which is as follows:

f is:

/root/path/to/mydir/test�.txt

newFile is:

/root/path/to/mydir/test_.txt

解决方案

The problem is that f.getName() returns the last name component of the path that is represented by f. You then massage this String and turn it back into a File. But the File now represents a path relative to the current directory, not the directory containing the original path.

As a result your code is actually attempting to rename the files from dirName into the application's current directory. That could fail because files already exist in the current directory with those names, or because the dirName and the current directory are in different file systems. (You cannot rename a file from one filesystem to another ... you have to copy it.)

Please note that a File in Java represents a pathname, not a file or a folder. In your code, the f objects are the pathnames for file system objects (either files or folders) in the directory denoted by the String dirname. Each of these f objects will have a directory part.

There is more than one way to fix your code; for example

change name = f.getName() to name = f.toString()

change new File(subbedName) to new File(f.getParentFile(), subbedName)

I have an alternative / additional theory.

The pathname of the file containing the \uFFFD character is coming out as "mojibake"; i.e. the kind of garbled text that you get when you display encoded text using the wrong encoding. And since we are seeing 3 characters of garbled text, I suspect that it is attempting to display the UTF-8 rendering of \uFFFD as Latin-1.

So my theory is that the same think is happening when the File.renameTo method is converting f to the form that it is going to provide to the system call. For some reason that is no clear to me, Java could be using the wrong encoding, and as a result producing a "name" for the original file that doesn't match the name of the file in the file system. That would be sufficient to cause the rename to fail.

Possibly related questions / links:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4733494 (Note that Sun decided this was not a Java bug, and most of the "me too" comments on the bug report are from people who do not understand the explanation ...)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值