File management

One of the key features of any build tool is I/O operations and how easily you can perform the I/O operations such as reading files, writing files, and directory-related operations. Developers with Ant or Maven backgrounds know how painful and complex it was to handle the files and directory operations in old build tools; sometimes you had to write custom tasks and plugins to perform these kinds of operations due to XML limitations in Ant and Maven. Since Gradle uses Groovy, it will make your life much easier while dealing with files and directory-related operations.

Reading files

Gradle provides simple ways to read the file. You just need to use the File API (application programing interface) and it provides everything to deal with the file. The following is the code snippet from FileExample/build.gradle:

task showFile << {
  File file1 = file("readme.txt")
  println file1    // will print name of the file
  file1.eachLine {
    println it  // will print contents line by line
  }
}

To read the file, we have used file(<file Name>). This is the default Gradle way to reference files because Gradle adds some path behavior ($PROJECT_PATH/<filename>) due to absolute and relative referencing of files. Here, the first println statement will print the name of the file which is readme.txt. To read a file, Groovy provides the eachLine method to the File API, which reads all the lines of the file one by one.

To access the directory, you can use the following file API:

def dir1 = new File("src")
println "Checking directory "+dir1.isFile() // will return false for directory
println "Checking directory "+dir1.isDirectory() // will return true for directory

Writing files

To write to the files, you can use either the append method to add contents to the end of the file or overwrite the file using the setText or write methods:

task fileWrite << {
  File file1 = file ("readme.txt")

  // will append data at the end
  file1.append("
Adding new line. 
")

  // will overwrite contents
  file1.setText("Overwriting existing contents")

  // will overwrite contents
  file1.write("Using write method")
}

Creating files/directories

You can create a new file by just writing some text to it:

task createFile << {
  File file1 = new File("newFile.txt")
  file1.write("Using write method")
}

By writing some data to the file, Groovy will automatically create the file if it does not exist.

To write content to file you can also use the leftshift operator (<<), it will append data at the end of the file:

file1 << "New content"

If you want to create an empty file, you can create a new file using the createNewFile() method.

task createNewFile << {
  File file1 = new File("createNewFileMethod.txt")
  file1.createNewFile()
}

A new directory can be created using the mkdir command. Gradle also allows you to create nested directories in a single command using mkdirs:

task createDir << {
  def dir1 = new File("folder1")
  dir1.mkdir()

  def dir2 = new File("folder2")
  dir2.createTempDir()

  def dir3 = new File("folder3/subfolder31")
  dir3.mkdirs() // to create sub directories in one command
}

In the preceding example, we are creating two directories, one using mkdir() and the other using createTempDir(). The difference is when we create a directory using createTempDir(), that directory gets automatically deleted once your build script execution is completed.

File operations

We will see examples of some of the frequently used methods while dealing with files, which will help you in build automation:

task fileOperations << {
  File file1 = new File("readme.txt")
  println "File size is "+file1.size()
  println "Checking existence "+file1.exists()
  println "Reading contents "+file1.getText()
  println "Checking directory "+file1.isDirectory()
  println "File length "+file1.length()
  println "Hidden file "+file1.isHidden()

  // File paths
  println "File path is "+file1.path
  println "File absolute path is "+file1.absolutePath
  println "File canonical path is "+file1.canonicalPath

// Rename file
file1.renameTo("writeme.txt")

// File Permissions
file1.setReadOnly()
println "Checking read permission "+ file1.canRead()+" write permission "+file1.canWrite()
file1.setWritable(true)
println "Checking read permission "+ file1.canRead()+" write permission "+file1.canWrite()

}

Most of the preceding methods are self-explanatory. Try to execute the preceding task and observe the output. If you try to execute the fileOperations task twice, you will get the exception readme.txt (No such file or directory) since you have renamed the file to writeme.txt.

Filter files

Certain file methods allow users to pass a regular expression as an argument. Regular expressions can be used to filter out only the required data, rather than fetch all the data. The following is an example of the eachFileMatch() method, which will list only the Groovy files in a directory:

task filterFiles << {
  def dir1 = new File("dir1")
  dir1.eachFileMatch(~/.*.groovy/) {
    println it
  }
  dir1.eachFileRecurse { dir ->
    if(dir.isDirectory()) {
      dir.eachFileMatch(~/.*.groovy/) {
        println it
      }
    }
  }
}

The output is as follows:

$ gradle filterFiles

:filterFiles
dir1groovySample.groovy
dir1subdir1groovySample1.groovy
dir1subdir2groovySample2.groovy
dir1subdir2subDir3groovySample3.groovy

BUILD SUCCESSFUL

Delete files and directories

Gradle provides the delete() and deleteDir() APIs to delete files and directories respectively:

task deleteFile << {
  def dir2 = new File("dir2")
  def file1 = new File("abc.txt")
  file1.createNewFile()
  dir2.mkdir()
  println "File path is "+file1.absolutePath
  println "Dir path is "+dir2.absolutePath
  file1.delete()
  dir2.deleteDir()
  println "Checking file(abc.txt) existence: "+file1.exists()+" and Directory(dir2) existence: "+dir2.exists()
}

The output is as follows:

$ gradle deleteFile
:deleteFile
File path is Chapter6/FileExample/abc.txt
Dir path is Chapter6/FileExample/dir2
Checking file(abc.txt) existence:  false and Directory(dir2) existence:  false

BUILD SUCCESSFUL

The preceding task will create a directory dir2 and a file abc.txt. Then it will print the absolute paths and finally delete them. You can verify whether it is deleted properly by calling the exists() function.

FileTree

Until now, we have dealt with single file operations. Gradle provides plenty of user-friendly APIs to deal with file collections. One such API is FileTree. A FileTree represents a hierarchy of files or directories. It extends the FileCollection interface. Several objects in Gradle such as sourceSets, implement the FileTree interface. You can initialize FileTree with the fileTree() method. The following are the different ways you can initialize the fileTree method:

task fileTreeSample << {
  FileTree fTree = fileTree('dir1')
  fTree.each {
    println it.name
  }
  FileTree fTree1 = fileTree('dir1') {
    include '**/*.groovy'
  }
  println ""
  fTree1.each {
    println it.name
  }
  println ""
FileTree fTree2 = fileTree(dir:'dir1',excludes:['**/*.groovy'])
  fTree2.each {
    println it.absolutePath
  }
}

Execute the gradle fileTreeSample command and observe the output. The first iteration will print all the files in dir1. The second iteration will only include Groovy files (with extension .groovy). The third iteration will exclude Groovy files (with extension .groovy) and print other files with absolute path.

You can also use FileTree to read contents from the archive files such as ZIP, JAR, or TAR files:

FileTree jarFile = zipTree('SampleProject-1.0.jar')
jarFile.each {
  println it.name
}

The preceding code snippet will list all the files contained in a jar file.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.14.245