rahul0789
rahul0789

Reputation: 337

How to change file extension at runtime in Java

I am trying to implement program to zip and unzip a file. All I want to do is to zip a file (fileName.fileExtension) with name as fileName.zip and on unzipping change it again to fileName.fileExtension.

Upvotes: 22

Views: 77461

Answers (8)

John Eipe
John Eipe

Reputation: 11228

This is how I used to rename files or change its extension.

public static void modify(File file) {
    int index = file.getName().lastIndexOf(".");
    // print filename
    // System.out.println(file.getName().substring(0, index));
    // print extension
    // System.out.println(file.getName().substring(index));
    String ext = file.getName().substring(index);
    // use file.renameTo() to rename the file
    file.renameTo(new File("Newname"+ext));
}

edit: John's method renames the file (keeping the extension). To change the extension do:

public static File changeExtension(File f, String newExtension) {
    int i = f.getName().lastIndexOf('.');
    String name = f.getName().substring(0,i);
    return new File(f.getParent(), name + newExtension);
}

This changes only the last extension to a filename, i.e. the .gz part of archive.tar.gz. Therefore it works fine with Linux hidden files, for which the name starts with a . This is quite safe because if getParent() returns null (i.e. in the event of the parent being the system root) it is "cast" to an empty String as the whole argument to the File constructor is evaluated first.

The only case where you will get a funny output is if you pass in a File representing the system root itself, in which case the null is prepended to the rest of the path string.

Upvotes: 15

invzbl3
invzbl3

Reputation: 6450

By the same logic as mentioned @hsz, but instead simply use replacement:

File file  = new File("fileName.fileExtension"); // creating object of File 
String str = file.getPath().replace(".fileExtension", ".zip"); // replacing extension to another 
file.renameTo(new File(str)); 

Upvotes: 4

Abheek Kumar Sarangi
Abheek Kumar Sarangi

Reputation: 45

My firend was working on a zipper in Java some 4 months back, I got this code from him.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFiles {

List<String> filesListInDir = new ArrayList<String>();

public static void main(String[] args) {
    File file = new File("/Users/pankaj/sitemap.xml");
    String zipFileName = "/Users/pankaj/sitemap.zip";
    
    File dir = new File("/Users/pankaj/tmp");
    String zipDirName = "/Users/pankaj/tmp.zip";
    
    zipSingleFile(file, zipFileName);
    
    ZipFiles zipFiles = new ZipFiles();
    zipFiles.zipDirectory(dir, zipDirName);
}

/**
 * This method zips the directory
 * @param dir
 * @param zipDirName
 */
private void zipDirectory(File dir, String zipDirName) {
    try {
        populateFilesList(dir);
        //now zip files one by one
        //create ZipOutputStream to write to the zip file
        FileOutputStream fos = new FileOutputStream(zipDirName);
        ZipOutputStream zos = new ZipOutputStream(fos);
        for(String filePath : filesListInDir){
            
   System.out.println("Zipping "+filePath);
            //for ZipEntry we need to keep only relative file path, so we used substring on absolute path
            ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length()));
            zos.putNextEntry(ze);
            //read the file and write to ZipOutputStream
            FileInputStream fis = new FileInputStream(filePath);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }
            zos.closeEntry();
            fis.close();
        }
        zos.close();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
   }

/**
 * This method populates all the files in a directory to a List
 * @param dir
 * @throws IOException
 */
   private void populateFilesList(File dir) throws IOException {
    File[] files = dir.listFiles();
    for(File file : files){
        if(file.isFile()) 
     filesListInDir.add(file.getAbsolutePath());
        else 
 populateFilesList(file);
    }
}

/**
 * This method compresses the single file to zip format
 * @param file
 * @param zipFileName
 */
private static void zipSingleFile(File file, String zipFileName) {
    try {
        //create ZipOutputStream to write to the zip file
        FileOutputStream fos = new FileOutputStream(zipFileName);
        ZipOutputStream zos = new ZipOutputStream(fos);
        //add a new Zip Entry to the ZipOutputStream
        ZipEntry ze = new ZipEntry(file.getName());
        zos.putNextEntry(ze);
        //read the file and write to ZipOutputStream
        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) > 0) {
            zos.write(buffer, 0, len);
        }
        
        //Close the zip entry to write to zip file
        zos.closeEntry();
        //Close resources
        zos.close();
        fis.close();
        fos.close();
        
    System.out.println(file.getCanonicalPath()+" is zipped to "+zipFileName);
        
    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

I haven't tried it personally, but he and also some of my other friends told me that it works.

Upvotes: 0

Sayed Abolfazl Fatemi
Sayed Abolfazl Fatemi

Reputation: 3911

If you are using Kotlin you can use from this property of your file object:

file.nameWithoutExtension + "extension"

Upvotes: 2

Mr. Lee
Mr. Lee

Reputation: 198

I want to avoid the new extension just happening to be in the path or filename itself. I like a combination of java.nio and apache StringFilenameUtils.

public void changeExtension(Path file, String extension) throws IOException {
    String newFilename = FilenameUtils.removeExtension(file.toString()) + EXTENSION_SEPARATOR_STR + extension;
    Files.move(file, Paths.get(newFilename, StandardCopyOption.REPLACE_EXISTING));
}

Upvotes: 2

JavaBohne
JavaBohne

Reputation: 181

I would check, if the file has an extension before changing. The solution below works also with files without extension or multiple extensions

public File changeExtension(File file, String extension) {
    String filename = file.getName();

    if (filename.contains(".")) {
        filename = filename.substring(0, filename.lastIndexOf('.'));
    }
    filename += "." + extension;

    file.renameTo(new File(file.getParentFile(), filename));
    return file;
}

@Test
public void test() {
    assertThat(changeExtension(new File("C:/a/aaa.bbb.ccc"), "txt"), 
                            is(new File("C:/a/aaa.bbb.txt")));

    assertThat(changeExtension(new File("C:/a/test"), "txt"), 
                            is(new File("C:/a/test.txt")));
}

Upvotes: 5

Pankaj
Pankaj

Reputation: 45

FilenameUtils.getFullPathNoEndSeparator(doc.getDocLoc()) + "/" +
     FilenameUtils.getBaseName(doc.getDocLoc()) + ".xml"

Upvotes: 0

hsz
hsz

Reputation: 152236

Try with:

File file  = new File("fileName.zip"); // handler to your ZIP file
File file2 = new File("fileName.fileExtension"); // destination dir of your file
boolean success = file.renameTo(file2);
if (success) {
    // File has been renamed
}

Upvotes: 8

Related Questions