Skip to main content

SequentialExtension - Java class



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
*/

Post a Comment

Most Popular on Agile Complexification Inverter

Where is Shakespeare When We Need Him?

We are desperately searching for a term for people that connotes the best of human kind.  The creative, sensing, combinatorial synergistic, empathic solutioning persons that have yet to been labeled with a role name that works.

Some of the old terms:
Staff, Workforce, Human Resource, My Team, Army, Company

Shakespeare created 1700 words in his time.  He mutated verbs to nouns, and vice-a-versa, transformed verbs into adjectives, and formed words from whole cloth never before heard.  This skill is rare, but there is a poet that can create the term we need in the twenty-first century.

What should this term define?

21st Century Human Resource; the generalizing specialist.

Yes, but what more?  What less?

Suggest your poetry in the comments, let us see if we cannot do 1/1700 as well as The Bard.

By-the-way; who create the phrase "coin a word"?



A TED Play List - How do you create new words
6:52
Erin McKeanGo ahead, make up new words! In this fun, short talk from TEDYouth, lexicographer Er…

Elements of an Effective Scrum Task Board

What are the individual elements that make a Scrum task board effective for the team and the leadership of the team?  There are a few basic elements that are quite obvious when you have seen a few good Scrum boards... but there are some other elements that appear to elude even the most servant of leaders of Scrum teams.









In general I'm referring to a physical Scrum board.  Although software applications will replicated may of the elements of a good Scrum board there will be affordances that are not easily replicated.  And software applications offer features not easily implemented in the physical domain also.





Scrum Info Radiator Checklist (PDF) Basic Elements
Board Framework - columns and rows laid out in bold colors (blue tape works well)
Attributes:  space for the total number of stickies that will need to belong in each cell of the matrix;  lines that are not easy eroded, but are also easy to replace;  see Orientation.

Columns (or Rows) - labeled
    Stories
    To Do
    Work In P…

Situational Leadership II Model & Theory

Have you ever been in a situation where you thought the technique needed to move forward was one thing, yet the person leading (your leader) assumed something else was what was needed?  Did you feel misaligned, unheard, marginalized?  Would you believe that 54% of all leaders only use ONE style of leadership - regardless of the situation?  Does that one style of leading work well for the many levels of development we see on a team?

Perhaps your team should investigate one of the most widely used leadership models in the world ("used to train over 5 million managers in the world’s most respected organizations").  And it's not just for the leaders.  The training is most effective when everyone receives the training and uses the model.  The use of a ubiquitous language on your team is a collaboration accelerator.  When everyone is using the same mental model, speaking the same vernacular hours of frustration and discussion may be curtailed, and alignment achieved, outcomes …

One Dark and Stormy during a Hurricane

I'm from the Carolina's where legend has it that our family commonly just hunkered down in the home on the coast and waterways than to head for inland shelter. Now that's from the old school days of barely improved (read paved) roads. They counted a storms severity by how high on the back porch steps (about 15 - top to ground) the water reached.  I don't recommend this action in todays world of long range forecast and transportation options.

I do recommend a drink or two in a hotel bar, far far away.

This is the week that Harvey came ashore in Texas.  I live on a hill in the little old town of Grapevine outside Dallas and Fort Worth.  And thank you all for letting me know that a storm is coming... I didn't get out and walk Malibu before the rain hit, so I grabbed a hat and we went anyway.  Much nicer walk with the drizzle, I'd say.

I'll raise a glass to you - if you were not smart enough to do the responsible thing, at the last responsible moment.

I do re…

Software Development terms applied to Home Construction

Let's Invert the typically wrong headed view of Software Development project management as a construction project.  We can map it the other way just to see if it works... to have some fun, to explore the meaning of phrases we toss around quite frequently.


Normally Project Management terms come from a construction domain.  We are going to apply the lexicon of modern software to the construction of a home.  We will follow the construction project and meet some of the people doing the work.

This is a very small (8 homes from $600,000 skyward) program in my 30-40 year old neighborhood.

About 6 months ago I saw the programs landing page go up.  It gives casual observers and some of the stakeholders a general idea of the intent of the program.  And most importantly who to contact for additional information if you happen to be interested in their products.

The Refuge program has 8 product projects and has them running independently.  Yet much of their DevOps infrastructure has already b…