Java-如果名称已经存在,则重命名输出文件,并考虑现有增量
在构建一个Android应用程序时,我发现需要进行一些文件复制。我想通过在文件名中添加一个增量字符串,在使用allready文件名的情况下获取新文件名。比如说Java-如果名称已经存在,则重命名输出文件,并考虑现有增量,java,regex,filenames,increment,Java,Regex,Filenames,Increment,在构建一个Android应用程序时,我发现需要进行一些文件复制。我想通过在文件名中添加一个增量字符串,在使用allready文件名的情况下获取新文件名。比如说 text.txt ---> text(1).txt 算法应考虑以下因素 1如果存在text.txt,则新文件名永远不应为text.txt1 2如果存在text1.txt,则新文件名应为text2.txt,而不是text11.txt 3如果存在text1foo.txt,则新文件名应为text1foo1.txt 第一个我已经准备好了,
text.txt ---> text(1).txt
算法应考虑以下因素
1如果存在text.txt,则新文件名永远不应为text.txt1
2如果存在text1.txt,则新文件名应为text2.txt,而不是text11.txt
3如果存在text1foo.txt,则新文件名应为text1foo1.txt
第一个我已经准备好了,但是第二个我有困难。正则表达式不是我的强项!使用正则表达式不是强制性的。每种方法都欢迎一些帮助
答复:
结合我的原始代码和这里的一个答案,我得出了这样一个结论,无论文件是否有扩展名,它在任何情况下都非常适合我:
public static File getFinalNewDestinationFile(File destinationFolder, File fileToCopy){
String destFolderPath = destinationFolder.getAbsolutePath()+File.separator;
File newFile = new File(destFolderPath + fileToCopy.getName());
String filename=fileToCopy.getName();
String nameWithoutExtentionOrIncrement;
String extension = getFileExtension(filename);
if(extension!=null){
extension="."+extension;
int extInd = filename.lastIndexOf(extension);
nameWithoutExtentionOrIncrement = new StringBuilder(filename).replace(extInd, extInd+extension.length(),"").toString();
}
else{
extension="";
nameWithoutExtentionOrIncrement = filename;
}
int c=0;
int indexOfClose = nameWithoutExtentionOrIncrement.lastIndexOf(")");
int indexOfOpen = nameWithoutExtentionOrIncrement.lastIndexOf("(");
if(indexOfClose!=-1 && indexOfClose!=-1 && indexOfClose==nameWithoutExtentionOrIncrement.length()-1 && indexOfClose > indexOfOpen && indexOfOpen!=0){
String possibleNumber = nameWithoutExtentionOrIncrement.substring(indexOfOpen+1, indexOfClose);
try{
c = Integer.parseInt(possibleNumber);
nameWithoutExtentionOrIncrement=nameWithoutExtentionOrIncrement.substring(0, indexOfOpen);
}catch(Exception e){c=0;}
}
while(newFile.exists()){
c++;
String path = destFolderPath + nameWithoutExtentionOrIncrement +"(" + Integer.toString(c) + ")" + extension;
newFile = new File(path);
}
return newFile;
}
public static String getFileExtension(String filename) {
if (filename == null) { return null; }
int lastUnixPos = filename.lastIndexOf('/');
int lastWindowsPos = filename.lastIndexOf('\\');
int indexOfLastSeparator = Math.max(lastUnixPos, lastWindowsPos);
int extensionPos = filename.lastIndexOf('.');
int lastSeparator = indexOfLastSeparator;
int indexOfExtension = lastSeparator > extensionPos ? -1 : extensionPos;
int index = indexOfExtension;
if (index == -1) {
return null;
} else {
return filename.substring(index + 1).toLowerCase();
}
}
我假设有两件事: 1名为fileExistsString fileName的方法可用。如果文件系统中已存在具有指定名称的文件,则返回true 2有一个名为FILE_NAME的常量,在您的示例中,该常量等于text
if (!fileExists(FILE_NAME)) {
//create file with FILE_NAME.txt as name
}
int availableIndex = 1;
while (true) {
if (!fileExists(currentName)) {
//create file with FILE_NAME(availableIndex).txt
break;
}
availableIndex++;
}
我假设有两件事: 1名为fileExistsString fileName的方法可用。如果文件系统中已存在具有指定名称的文件,则返回true 2有一个名为FILE_NAME的常量,在您的示例中,该常量等于text
if (!fileExists(FILE_NAME)) {
//create file with FILE_NAME.txt as name
}
int availableIndex = 1;
while (true) {
if (!fileExists(currentName)) {
//create file with FILE_NAME(availableIndex).txt
break;
}
availableIndex++;
}
我对Android不是很确定,但因为它是一个Java程序,所以您可以创建要写入的目录的文件对象。 一旦你有了它,你就可以看到里面已经存在的文件名列表和其他相关信息。然后您可以根据上述逻辑确定文件名
File dir = new File("<dir-path>");
if(dir.isDirectory()){
String[] files = dir.list();
for(String fileName : files){
<logic for finding filename>
}
}
我对Android不是很确定,但因为它是一个Java程序,所以您可以创建要写入的目录的文件对象。 一旦你有了它,你就可以看到里面已经存在的文件名列表和其他相关信息。然后您可以根据上述逻辑确定文件名
File dir = new File("<dir-path>");
if(dir.isDirectory()){
String[] files = dir.list();
for(String fileName : files){
<logic for finding filename>
}
}
如果所有文件名都有一个扩展名,您可以这样做,只是一个示例,您必须将其更改为适用于您的情况:
public static void main(String[] args)
{
String test = "test(1)foo.txt";
String test1 = "test(1)foo(1).txt";
Pattern pattern = Pattern.compile("((?<=\\()\\d+(?=\\)\\.))");
Matcher matcher = pattern.matcher(test);
String fileOutput = "";
String temp = null;
int newInt = -1;
while(matcher.find())
{
temp = matcher.group(0);
}
if(temp != null)
{
newInt = Integer.parseInt(temp);
newInt++;
fileOutput = test.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
}
else
{
fileOutput = test;
}
System.out.println(fileOutput);
matcher = pattern.matcher(test1);
fileOutput = "";
temp = null;
while(matcher.find())
{
temp = matcher.group(0);
}
if(temp != null)
{
newInt = Integer.parseInt(temp);
newInt++;
fileOutput = test1.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
}
else
{
fileOutput = test1;
}
System.out.println(fileOutput);
}
输出:
test1foo.txt
test1foo2.txt
它使用正则表达式在最后一个之前的右边查找数字
更新
replaceAll已更改,以处理发生故障的情况。在test1.foo1.txt中的第一个1之后。如果所有文件名都有一个扩展名,您可以执行类似的操作,这只是一个示例,您必须将其更改为适用于您的情况:
public static void main(String[] args)
{
String test = "test(1)foo.txt";
String test1 = "test(1)foo(1).txt";
Pattern pattern = Pattern.compile("((?<=\\()\\d+(?=\\)\\.))");
Matcher matcher = pattern.matcher(test);
String fileOutput = "";
String temp = null;
int newInt = -1;
while(matcher.find())
{
temp = matcher.group(0);
}
if(temp != null)
{
newInt = Integer.parseInt(temp);
newInt++;
fileOutput = test.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
}
else
{
fileOutput = test;
}
System.out.println(fileOutput);
matcher = pattern.matcher(test1);
fileOutput = "";
temp = null;
while(matcher.find())
{
temp = matcher.group(0);
}
if(temp != null)
{
newInt = Integer.parseInt(temp);
newInt++;
fileOutput = test1.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
}
else
{
fileOutput = test1;
}
System.out.println(fileOutput);
}
输出:
test1foo.txt
test1foo2.txt
它使用正则表达式在最后一个之前的右边查找数字
更新
replaceAll已更改,以处理发生故障的情况。在test1.foo1.txt中的第一个1之后。这里有一种方法:
String fileName;
File file = new File(fileName);
if(file.exists()) {
int dot = fileName.lastIndexOf('.'), open = fileName.lastIndexOf('('), incr;
boolean validNum = false;
if(fileName.charAt(dot-1) == ')' && open != -1){
String n = fileName.substring(open+1, dot-1);
try {
incr = Integer.parseInt(n);
validNum = true;
} catch(NumberFormatException e) {
validNum = false;
}
}
if(validNum) {
String pre = fileName.substring(0, open+1), post = fileName.substring(0, dot-1);
while(new File(pre + ++incr + post).exists());
fileName = pre + incr + post;
} else {
fileName = fileName.substring(0, dot) + "(1)" + fileName.substring(dot);
}
}
这里有一种方法:
String fileName;
File file = new File(fileName);
if(file.exists()) {
int dot = fileName.lastIndexOf('.'), open = fileName.lastIndexOf('('), incr;
boolean validNum = false;
if(fileName.charAt(dot-1) == ')' && open != -1){
String n = fileName.substring(open+1, dot-1);
try {
incr = Integer.parseInt(n);
validNum = true;
} catch(NumberFormatException e) {
validNum = false;
}
}
if(validNum) {
String pre = fileName.substring(0, open+1), post = fileName.substring(0, dot-1);
while(new File(pre + ++incr + post).exists());
fileName = pre + incr + post;
} else {
fileName = fileName.substring(0, dot) + "(1)" + fileName.substring(dot);
}
}
使用一个正则表达式模式:
final static Pattern PATTERN = Pattern.compile("(.*?)(?:\\((\\d+)\\))?(\\.[^.]*)?");
String getNewName(String filename) {
if (fileExists(filename)) {
Matcher m = PATTERN.matcher(filename);
if (m.matches()) {
String prefix = m.group(1);
String last = m.group(2);
String suffix = m.group(3);
if (suffix == null) suffix = "";
int count = last != null ? Integer.parseInt(last) : 0;
do {
count++;
filename = prefix + "(" + count + ")" + suffix;
} while (fileExists(filename));
}
}
return filename;
}
正则表达式模式解释:
.*? 一个非贪婪的匹配一切从一开始
?:\\\\d+\\?括号中的数字是可选的
?:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
___\\______\\_-火柴和
______\\d+___;-匹配并捕获一个或多个数字
\\.[^.]+? 点后跟除点以外的任何选项(可选)
使用一个正则表达式模式:
final static Pattern PATTERN = Pattern.compile("(.*?)(?:\\((\\d+)\\))?(\\.[^.]*)?");
String getNewName(String filename) {
if (fileExists(filename)) {
Matcher m = PATTERN.matcher(filename);
if (m.matches()) {
String prefix = m.group(1);
String last = m.group(2);
String suffix = m.group(3);
if (suffix == null) suffix = "";
int count = last != null ? Integer.parseInt(last) : 0;
do {
count++;
filename = prefix + "(" + count + ")" + suffix;
} while (fileExists(filename));
}
}
return filename;
}
正则表达式模式解释:
.*? 一个非贪婪的匹配一切从一开始
?:\\\\d+\\?括号中的数字是可选的
?:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
___\\______\\_-火柴和
______\\d+___;-匹配并捕获一个或多个数字
\\.[^.]+? 点后跟除点以外的任何选项(可选)
你必须使用正则表达式吗?看来你可以做得更容易,否则..不,这不是强制性的…我只是想,ti会更有效的方式。欢迎任何方法!您不能在正则表达式中递增数字。@noob但您可以使用正则表达式提取需要递增的部分,以及需要保持不变的部分。是否必须使用正则表达式?看来你可以做得更容易,否则..不,这不是强制性的…我只是想,ti会更有效的方式。欢迎任何方法!您不能在正则表达式中递增数字。@noob但您可以使用正则表达式提取需要递增的部分,以及需要保持不变的部分。非常优雅和快速的方法可能会重复。唯一的缺点是,如果文件以结尾。增量添加在..之后。。示例foo.->foo.1在以前没有扩展的地方添加扩展。@Anonymous将正则表达式的结尾从\\.[^.]+?至\\.[^.]*?还有福。将成为一种非常优雅和快捷的方式。唯一的缺点是,如果文件以结尾。增量添加在..之后。。示例foo.->foo.1在以前没有扩展的地方添加扩展。@Anonymous更改正则表达式f的结尾 rom\\.[^.]+?至\\.[^.]*?还有福。将成为foo1。