
- •Contents at a Glance
- •Contents
- •About the Authors
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Oracle Java Certifications: Overview
- •FAQ 1. What are the different levels of Oracle Java certification exams?
- •FAQ 4. Is OCPJP 7 prerequisite for other Oracle certification exams?
- •FAQ 5. Should I take the OCPJP 7 or OCPJP 6 exam?
- •The OCPJP 7 Exam
- •FAQ 7. How many questions are there in the OCPJP 7 exam?
- •FAQ 8. What is the duration of the OCPJP 7 exam?
- •FAQ 9. What is the cost of the OCPJP 7 exam?
- •FAQ 10. What are the passing scores for the OCPJP 7 exam?
- •FAQ 11. What kinds of questions are asked in the OCPJP 7 exam?
- •FAQ 12. What does the OCPJP 7 exam test for?
- •FAQ 13. I’ve been a Java programmer for last five years. Do I have to prepare for the OCPJP 7 exam?
- •FAQ 14. How do I prepare for the OCPJP 7 exam?
- •FAQ 15. How do I know when I’m ready to take the OCPJP 7 exam?
- •Taking the OCPJP 7 Exam
- •FAQ 16. What are my options to register for the exam?
- •FAQ 17. How do I register for the exam, schedule a day and time for taking the exam, and appear for the exam?
- •The OCPJP 7 Exam: Pretest
- •Answers with Explanations
- •Post-Pretest Evaluation
- •Essentials of OOP
- •FunPaint Application: An Example
- •Foundations of OOP
- •Abstraction
- •Encapsulation
- •Inheritance
- •Polymorphism
- •Class Fundamentals
- •Object Creation
- •Constructors
- •Access Modifiers
- •Public Access Modifier
- •Private Access Modifier
- •Protected and Default Access Modifier
- •Overloading
- •Method Overloading
- •Constructor Overloading
- •Overload resolution
- •Points to Remember
- •Inheritance
- •Runtime Polymorphism
- •An Example
- •Overriding Issues
- •Overriding: Deeper Dive
- •Invoking Superclass Methods
- •Type Conversions
- •Upcasts and Downcasts
- •Casting Between Inconvertible Types
- •Using “instanceof” for Safe Downcasts
- •Java Packages
- •Working with Packages
- •Static Import
- •Summary
- •Abstract Classes
- •Points to Remember
- •Using the “final” Keyword
- •Final Classes
- •Final Methods and Variables
- •Points to Remember
- •Using the “static” Keyword
- •Static Block
- •Points to Remember
- •Flavors of Nested Classes
- •Static Nested Classes (or Interfaces)
- •Points to Remember
- •Inner Classes
- •Points to Remember
- •Local Inner Classes
- •Points to Remember
- •Anonymous Inner Classes
- •Points to Remember
- •Enum Data Types
- •Points to Remember
- •Summary
- •Interfaces
- •Declaring and Using Interfaces
- •Points to Remember
- •Abstract Classes vs. Interfaces
- •Choosing Between an Abstract Class and an Interface
- •Object Composition
- •Composition vs. Inheritance
- •Points to Remember
- •Design Patterns
- •The Singleton Design Pattern
- •Ensuring That Your Singleton Is Indeed a Singleton
- •The Factory Design Pattern
- •Differences Between Factory and Abstract Factory Design Patterns
- •The Data Access Object (DAO) Design Pattern
- •Points to Remember
- •Summary
- •Generics
- •Using Object Type and Type Safety
- •Using the Object Class vs. Generics
- •Container Implementation Using the Object Class
- •Container Implementation Using Generics
- •Creating Generic Classes
- •Diamond Syntax
- •Interoperability of Raw Types and Generic Types
- •Generic Methods
- •Generics and Subtyping
- •Wildcard Parameters
- •Limitations of Wildcards
- •Bounded Wildcards
- •Wildcards in the Collections Class
- •Points to Remember
- •The Collections Framework
- •Why Reusable Classes?
- •Basic Components of the Collections Framework
- •Abstract Classes and Interfaces
- •Concrete Classes
- •List Classes
- •ArrayList Class
- •The ListIterator Interface
- •The LinkedList Class
- •The Set Interface
- •The HashSet Class
- •The TreeSet Class
- •The Map Interface
- •The HashMap Class
- •Overriding the hashCode() Method
- •The NavigableMap Interface
- •The Queue Interface
- •The Deque Interface
- •Comparable and Comparator Interfaces
- •Algorithms (Collections Class)
- •The Arrays Class
- •Methods in the Arrays Class
- •Array as a List
- •Points to Remember
- •Summary
- •Generics
- •Collections Framework
- •Processing Strings
- •String Searching
- •The IndexOf() Method
- •The regionMatches() Method
- •String Parsing
- •String Conversions
- •The Split() Method
- •Regular Expressions
- •Understanding regex Symbols
- •Regex Support in Java
- •Searching and Parsing with regex
- •Replacing Strings with regex
- •String Formatting
- •Format Specifiers
- •Points to Remember
- •Summary
- •Reading and Writing from Console
- •Understanding the Console Class
- •Formatted I/O with the Console Class
- •Special Character Handling in the Console Class
- •Using Streams to Read and Write Files
- •Character Streams and Byte Streams
- •Character Streams
- •Reading Text Files
- •Reading and Writing Text Files
- •“Tokenizing” Text
- •Byte Streams
- •Reading a Byte Stream
- •Data Streams
- •Writing to and Reading from Object Streams: Serialization
- •Serialization: Some More Details
- •Points to Remember
- •Summary
- •A Quick History of I/O APIs
- •Using the Path Interface
- •Getting Path Information
- •Comparing Two Paths
- •Using the Files Class
- •Checking File Properties and Metadata
- •Copying a File
- •Moving a File
- •Deleting a File
- •Walking a File Tree
- •Revisiting File Copy
- •Finding a File
- •Watching a Directory for Changes
- •Points to Remember
- •Summary
- •Introduction to JDBC
- •The Architecture of JDBC
- •Two-Tier and Three-Tier JDBC Architecture
- •Types of JDBC Drivers
- •Setting Up the Database
- •Connecting to a Database Using a JDBC Driver
- •The Connection Interface
- •Connecting to the Database
- •Statement
- •ResultSet
- •Querying the Database
- •Updating the Database
- •Getting the Database Metadata
- •Points to Remember
- •Querying and Updating the Database
- •Performing Transactions
- •Rolling Back Database Operations
- •The RowSet Interface
- •Points to Remember
- •Summary
- •Define the Layout of the JDBC API
- •Connect to a Database by Using a JDBC driver
- •Update and Query a Database
- •Customize the Transaction Behavior of JDBC and Commit Transactions
- •Use the JDBC 4.1 RowSetProvider, RowSetFactory, and RowSet Interfaces
- •Introduction to Exception Handling
- •Throwing Exceptions
- •Unhandled Exceptions
- •Try and Catch Statements
- •Programmatically Accessing the Stack Trace
- •Multiple Catch Blocks
- •Multi-Catch Blocks
- •General Catch Handlers
- •Finally Blocks
- •Points to Remember
- •Try-with-Resources
- •Closing Multiple Resources
- •Points to Remember
- •Exception Types
- •The Exception Class
- •The RuntimeException Class
- •The Error Class
- •The Throws Clause
- •Method Overriding and the Throws Clause
- •Points to Remember
- •Custom Exceptions
- •Assertions
- •Assert Statement
- •How Not to Use Asserts
- •Summary
- •Introduction
- •Locales
- •The Locale Class
- •Getting Locale Details
- •Resource Bundles
- •Using PropertyResourceBundle
- •Using ListResourceBundle
- •Loading a Resource Bundle
- •Naming Convention for Resource Bundles
- •Formatting for Local Culture
- •The NumberFormat Class
- •The Currency Class
- •The DateFormat Class
- •The SimpleDateFormat Class
- •Points to Remember
- •Summary
- •Introduction to Concurrent Programming
- •Important Threading-Related Methods
- •Creating Threads
- •Extending the Thread Class
- •Implementing the Runnable Interface
- •The Start( ) and Run( ) Methods
- •Thread Name, Priority, and Group
- •Using the Thread.sleep() Method
- •Using Thread’s Join Method
- •Asynchronous Execution
- •The States of a Thread
- •Two States in “Runnable” State
- •Concurrent Access Problems
- •Data Races
- •Thread Synchronization
- •Synchronized Blocks
- •Synchronized Methods
- •Synchronized Blocks vs. Synchronized Methods
- •Deadlocks
- •Other Threading Problems
- •Livelocks
- •Lock Starvation
- •The Wait/Notify Mechanism
- •Let’s Solve a Problem
- •More Thread States
- •timed_waiting and blocked States
- •waiting State
- •Using Thread.State enum
- •Understanding IllegalThreadStateException
- •Summary
- •Using java.util.concurrent Collections
- •Semaphore
- •CountDownLatch
- •Exchanger
- •CyclicBarrier
- •Phaser
- •Concurrent Collections
- •Apply Atomic Variables and Locks
- •Atomic Variables
- •Locks
- •Conditions
- •Multiple Conditions on a Lock
- •Use Executors and ThreadPools
- •Executor
- •Callable, Executors, ExecutorService, ThreadPool, and Future
- •ThreadFactory
- •The ThreadLocalRandom Class
- •TimeUnit Enumeration
- •Use the Parallel Fork/Join Framework
- •Useful Classes of the Fork/Join Framework
- •Using the Fork/Join Framework
- •Points to Remember
- •Summary
- •Using java.util.concurrent Collections
- •Applying Atomic Variables and Locks
- •Using Executors and ThreadPools
- •Using the Parallel Fork/Join Framework
- •Chapter 3: Java Class Design
- •Chapter 4: Advanced Class Design
- •Chapter 5: Object-Oriented Design Principles
- •Chapter 6: Generics and Collections
- •Chapter 7: String Processing
- •Chapter 8: Java I/O Fundamentals
- •Chapter 9: Java File I/O (NIO.2)
- •Chapter 10: Building Database Applications with JDBC
- •Chapter 11: Exceptions and Assertions
- •Chapter 12: Localization
- •Chapter 13: Threads
- •Chapter 14: Concurrency
- •OCPJP7 Exam (1Z0-804 a.k.a. Java SE 7 Programmer II) Topics
- •OCPJP 7 Exam (1Z0-805, a.k.a. Upgrade to Java SE 7 Programmer) Topics
- •Answers and Explanations
- •Answer Sheet
- •Answers and Explanations
- •Index
chapter 9 ■ Java File I/O (NIO.2)
You use the readAttribute() method along with BasicFileAttributes to retrieve basic file properties. Similarly, you can retrieve attributes associated with a file in a DOS or UNIX environment using DosFileAttributes and PosixFileAttributes, respectively.
Copying a File
Now let’s try copying a file/directory from one location to another location. This task is easy to accomplish: just call Files.copy() to copy the file from source to target. Here is the signature of this method:
Path copy(Path source, Path target, CopyOption. . . options)
Listing 9-9 uses this method to write a simple file copy program.
Listing 9-9. FileCopy.java
import java.io.IOException; import java.nio.file.*;
public class FileCopy {
public static void main(String[] args) { if(args.length != 2){
System.out.println("usage: FileCopy <source-path> <destination-path>"); System.exit(1);
}
Path pathSource = Paths.get(args[0]); Path pathDestination = Paths.get(args[1]); try {
Files.copy(pathSource, pathDestination); System.out.println("Source file copied successfully");
} catch (IOException e) { e.printStackTrace();
}
}
}
Let’s execute it and see whether it works.
D:\> java FileCopy FileCopy.java Backup.java Source file copied successfully
Yes, it’s working. Let’s try running it again with same arguments.
D:\OCPJP7\programs\NIO2\src>java FileCopy FileCopy.java Backup.java java.nio.file.FileAlreadyExistsException: Backup.java
at sun.nio.fs.WindowsFileCopy.copy(Unknown Source) [. . .stack trace elided. . .]
Oops! What happened? When you tried copying the file for the second time, you got a FileAlreadyExistsException since the destination file already exists. So, what if you want to overwrite the existing
264

chapter 9 ■ Java File I/O (NIO.2)
file? The solution: you need to tell the copy() method that you would like to overwrite an existing file. In Listing 9-9, change the copy() method as follows:
Files.copy(pathSource, pathDestination, StandardCopyOption.REPLACE_EXISTING);
In this change, you are specifying an additional argument (since the copy() method supports variable arguments) to tell the method that you want to overwrite a file if it already exists. So, let’s run this program and see whether it works.
D:\>java FileCopy FileCopy.java Backup.java Source file copied successfully
D:\>java FileCopy FileCopy.java Backup.java Source file copied successfully
Yes, it works. Now, try to copy a file to a new directory.
D:\OCPJP7\programs\NIO2\src>java FileCopy FileCopy.java bak\Backup.java java.nio.file.NoSuchFileException: FileCopy.java -> bak\Backup.java
[. . .stack trace elided . . .]
Well, here you tried to copy a file to back directory that does not exist. For this, you got the NoSuchFileException. Note that not just the given directory but all intermediate directories in a path must exist for the copy() method to succeed.
All the directories (except the last one if you are copying a directory) in the specified path must exist to avoid NoSuchFileException.
What if you try copying a directory? It will work, but remember that it will only copy the top-level directory, not the not the files/directories contained within that directory.
If you copy a directory using the copy() method, it will not copy the files/directories contained in the source directory; you need to explicitly copy them to the destination folder.
You will revisit this topic later in this chapter when you implement a copy program that can copy a directory into another directory along with the contained files/directories.
Moving a File
Moving a file is quite similar to copying a file; for this purpose, you can use the Files.move() method. The signature of this method is
Path move(Path source, Path target, CopyOption. . . options)
265
chapter 9 ■ Java File I/O (NIO.2)
Listing 9-10 contains a small program that uses this method.
Listing 9-10. FileMove.java
import java.io.IOException; import java.nio.file.*;
public class FileMove {
public static void main(String[] args) { if(args.length != 2){
System.out.println("usage: FileMove <source-path> <destination-path>"); System.exit(−1);
}
Path pathSource = Paths.get(args[0]); Path pathDestination = Paths.get(args[1]); try {
Files.move(pathSource, pathDestination, StandardCopyOption.REPLACE_EXISTING); System.out.println("Source file moved successfully");
} catch (IOException e) { e.printStackTrace();
}
}
}
This basic implementation works fine. However, here are some observations peculiar to the move() method:
•As is the case with the copy() method, the move() method also does not overwrite the existing destination file unless you specify it to do so using REPLACE_EXISTING.
•If you move a symbolic link, the link itself will be moved, not the target file of the link. It is important to note that in the case of the copy() method, if you specify a symbolic link, the target of the link is copied, not the link itself.
•A non-empty directory can be moved if moving the directory does not require moving the containing files/directories. For instance, moving a directory from one physical drive to another might be unsuccessful (an IOException will be thrown). If moving a directory operation is successful, then all the contained files/directories will also be moved.
•You can specify a move() operation as an atomic operation using the ATOMIC_MOVE copy option. If move() is performed as a non-atomic operation and it fails in between, the state of both files is unknown and undefined.
Deleting a File
The Files class provides a delete() method to delete a file/directory/symbolic link. Listing 9-11 contains a simple program to delete a specified file.
Listing 9-11. FileDelete.java
import java.io.IOException; import java.nio.file.*;
public class FileDelete {
public static void main(String[] args) {
266