SequentialExtension is a Java class to create filenames with a sequential extension. Given a directory with file.001, file.002, file.005; what is the next sequential filename? Either file.003 or file.006 - this utility class will return either java.io.File based on your desire for infix mode (file.003) or not (file.006).
Get the Java source code for SequentialExtension.java.
A utility class for generating sequential file extensions.
Assume a directory with:
|- file.name.001
|- file.name.002
|- file.name.005
What is the next file name in the sequential set?
file.name.006 or maybe file.name.003
Depends on what you want to do.
The method nextSequentialFile will generate a File object to meet either need.
/*
* Copyright (c) 2003 David A. Koontz
* Licensed under the Open Software License version 2.0
*/
import java.io.*;
/**
* Utility class for generating sequential file extensions.
*
*
* Assume a directory with:
*
* |- file.name.001
* |- file.name.002
* |- file.name.005
*
* What is the next file name in the sequential set?
* file.name.006 or maybe file.name.003
* Depends on what you want to do.
*
* The method nextSequentialFile will generate a
* File object to meet either need.
*
* @author David A. Koontz
*/
public class SequentialExtension {
/**
* Finds the next file extension of a sequential extension.
*
* Given file.001, file.002, file.005 in a directory this
* method will return file.003 when infix == true
* or file.006 when infix == false.
*
* If baseName is null or empty string then every file within the
* directory is considered within the sequential set.
*
* @param directory the directory in which to search
* @param baseName the filename's base part
* @param infix when true gaps in sequence will be infiled
* @return the File with the next sequential number
*/
public File nextSequentialFile(File directory, String baseName, boolean infix) {
File seqFile = null;
if( (directory==null) || (!directory.isDirectory()) )
throw new IllegalArgumentException("Invalid directory");
if ( infix ) {
// start with *.000 or *.001
// int next = 1; // if you want to start with *.001
// just for sanity we limit the sequence loop to *.999
for ( int next = 0; next < 1000; next++ ) {
// generate the next extension in sequential set
String numStr = makeNumericExtension(next);
seqFile = new File(directory, baseName + '.' + numStr);
if ( ! seqFile.exists() ) {
break; // found a non-existant file name - break out of loop & return it
}
}
if ( seqFile == null ) {
throw new UnsupportedOperationException("All sequential files 000 - 999 exist for "+baseName+"!");
}
} else {
// not inclusive - meaning generate extension at end of current set
// so file.001, file.002, file.005 results in file.006
int max = findMaxSequentialExtension(directory, baseName);
int next = max + 1;
// generate the next extension in sequential set
String numStr = makeNumericExtension(next);
seqFile = new File( directory, baseName + '.' + numStr );
}
return seqFile;
}
/**
* Generate a three digit extension (zero padded).
*
* Like: "003" or "023" (also "4321").
*/
private static String makeNumericExtension(int number) {
String numStr = "" + number;
if ( numStr.length() == 1 )
numStr = "00" + number;
else if ( numStr.length() == 2 )
numStr = "0" + number;
return numStr;
}
/**
* Finds the next file extension of a sequential extension.
*
* Given file.001, file.002, file.005 in a directory this
* method will return file.003.
*
* If baseName is null or empty string then every file within the
* directory is considered within the sequential set.
*
* @param directory the directory in which to search
* @param baseName the filename's base part
* @return the File with the next sequential number
*/
public File nextSequentialFile(File directory, String baseName) {
if( (directory==null) || (!directory.isDirectory()) )
throw new IllegalArgumentException("Invalid directory");
// start with *.000 or *.001
// int next = 1; // if you want to start with *.001
// just for sanity we limit the sequence loop to *.999
File seqFile = null;
for ( int next = 0; next < 1000; next++ ) {
// generate the next extension in sequential set
String numStr = "" + next;
if ( numStr.length() == 1 )
numStr = "00"+next;
else if ( numStr.length() == 2 )
numStr = "0"+next;
seqFile = new File(directory, baseName + '.' + numStr);
if ( ! seqFile.exists() ) {
break; // found a non-existant file name - break out of loop & return it
}
}
if ( seqFile == null ) {
throw new UnsupportedOperationException("All sequential files 000 - 999 exist for "+baseName+"!");
}
return seqFile;
}
/**
* Finds the max file extension of a sequential file.
*
* Given file.001, file.002, file.005 in a directory this
* method will return 5.
*
* Uses a FileFilter to search the directory if baseName is
* provided. If baseName is null or empty string then every
* file within the directory is considered within the sequential set.
*
* @param directory the directory in which to search
* @param baseName the filename's base part
* @return the max sequential number
*/
private int findMaxSequentialExtension(File directory, String baseName) {
if( (directory==null) || (!directory.isDirectory()) )
throw new IllegalArgumentException("Invalid directory");
// start with *.000
// int maxValue = 0; // if you want to start with *.001
int maxValue = -1;
File[] files;
if ( baseName!=null && baseName.length()>0 ) {
files = directory.listFiles(new BaseNameFilter(baseName));
} else {
files = directory.listFiles();
}
for(int i=0; i < files.length; i++) {
// ignore directories & do not recurse into sub-dir
if(files[i].isFile()) {
String name = files[i].getName();
int dotIndex = name.lastIndexOf('.');
// if no dot lastIndexOf returns -1
// what about unix hidden (dot) files
if (dotIndex > 0) {
// only if there is a basename
String ext = name.substring(dotIndex+1);
System.out.println( "found ext = " + ext );
try {
int num = Integer.parseInt(ext);
if ( num > maxValue ) maxValue=num;
}catch(NumberFormatException nfe) {
; // ignore
}
}
}
}
return maxValue;
}
/**
* Strips path and extension from a filename.
*
*/
public static String getBaseName( String name )
{
// strip path.
String base = new File( name ).getName();
// strip possible extension.
int index = base.lastIndexOf( '.' );
if( index != -1 )
base = base.substring( 0, index );
return base;
}
/**
* Strips path and extension from a filename.
*
* example: path/file.name.txt -> file.name
*
* Note: define extension as the substring after the last dot.
*
*/
public static String getBaseName( File name )
{
// strip path.
String base = name.getName();
// strip possible extension.
int index = base.lastIndexOf( '.' );
if( index != -1 )
base = base.substring( 0, index );
return base;
}
/**
* Strips path and base name from a filename.
*
* example: path/file.txt -> txt
*
* Note: define extension as the substring after the last dot.
*
* example: path/long.file.name.ext -> ext
*/
public static String getFileExtension( File file, boolean keepDot )
{
// strip path
String base = file.getName();
// strip possible extension
String extension = "";
int index = base.lastIndexOf( '.' );
if( index != -1 )
{
if( keepDot )
extension = base.substring( index );
else
extension = base.substring( index + 1 );
}
return extension;
}
/**
* A Filter for filenames of a given base name.
*
* For use in File.listFiles
*
* File[] files = directory.listFiles(BaseNameFilter("MyFile"));
*
* Would return MyFile.001, MyFile.002, MyFile.txt, etc.
*/
class BaseNameFilter implements FileFilter {
// inner class
private String name;
BaseNameFilter(String baseName) {
name = baseName;
}
public boolean accept(File f) {
//
String bn = getBaseName(f.getName());
// is file system case sensitive? how would I know?
// shouldn't Java System know?
// if ( name.equalsIgnoreCase(bn) ) {
if ( name.equals(bn) ) {
return true;
}
return false;
}
}
/**
* A Filter for filenames of a given extension.
*
* For use in File.listFiles
*
* File[] files = directory.listFiles(ExtensionFilter("txt"));
*
* Would return junk.txt, apple.txt, MyFile.txt, etc.
*/
class ExtensionFilter implements FileFilter {
// inner class
private String name;
ExtensionFilter(String extension) {
name = extension;
}
public boolean accept(File f) {
//
String ext = getFileExtension(f, false);
// is file system case sensitive? how would I know?
// shouldn't Java System know?
// if ( name.equalsIgnoreCase(ext) ) {
if ( name.equals(ext) ) {
return true;
}
return false;
}
}
/**
* Unit testing the Filters & findMaxSequentialExtension()
*/
public static void main( String[] args ) {
File nextFile = null;
String baseName = "file.name";
SequentialExtension se = new SequentialExtension(".");
// generate the next extension (not infix) in sequential set
nextFile = se.nextSequentialFile(se.cwd, baseName, false);
try {
if ( nextFile.createNewFile() ) {
System.out.println("Created " + nextFile.getName() );
} else {
System.out.println("Failed to create " + nextFile.getName() );
}
} catch (IOException ex) {
System.out.println("Failed" + ex);
}
// generate the infixed extension within a sequential set
nextFile = se.nextSequentialFile(se.cwd, baseName, true);
try {
if ( nextFile.createNewFile() ) {
System.out.println("Created " + nextFile.getName() );
} else {
System.out.println("Failed to create " + nextFile.getName() );
}
} catch (IOException ex) {
System.out.println("Failed" + ex);
}
se.list(baseName);
/* This is program output after a few runs & deleting a few files
Note the missing files (003 & 004).
found ext = 000
found ext = 001
found ext = 002
found ext = 005
found ext = 006
Created file.name.007
Created file.name.003
List of 'file.name' files:
file.name.000
file.name.001
file.name.002
file.name.005
file.name.006
file.name.007
file.name.003
*/
se.list();
}
File cwd;
public SequentialExtension(String dir) {
cwd = new File(dir);
}
public void list(String basename) {
File[] files = cwd.listFiles(new BaseNameFilter(basename) );
System.out.println("List of '" + basename + "' files:");
for (int i = 0; i < files.length; i++) {
System.out.println(" "+ files[i].getName() );
}
}
public void list() {
File[] files = cwd.listFiles( );
System.out.println("List of files:");
for (int i = 0; i < files.length; i++) {
System.out.println(" "+ files[i].getName() );
}
}
}
/*
* Copyright (c) 2003 David A. Koontz
* Licensed under the Open Software License version 2.0
*/
Comments