Tip

Determining free disk space on Windows NT

Determining Free Disk Space on Windows NT

From Oracle PL/SQL programming by Steve Feurstein with Bill Pribyl, O'Reilly and Associates, 1997

Here is an external procedure that will discover the amount of free space on a given disk drive. This example is just to get you going. We won't try to explain all the details at this point. This example was designed for Windows NT 4.0, but the idea can be applied to any operating system that meets the requirements for external procedures. In this case, we simply make a call to the appropriate function in the Windows kernel, rather than writing our own DLL.

Windows NT's kernel, kernel32.dll, contains a routine called GetDiskFreeSpaceA, which accepts a drive letter as an input parameter and returns four statistics about the drive. When we register the routine with PL/SQL, we will provide mappings for each of these parameters to a PL/SQL parameter. Then, when we invoke the external procedure from a PL/SQL program, we'll use these statistics to compute the free disk space.

First, we need to define a "library" to tell Oracle where the DLL lives:


 	/*Filename on companion disk: nt_space.sql*/
 	CREATE OR REPLACE LIBRARY nt_kernel
 	AS
 	     'c:winntsystem32kernel32.dll';
 

We'll create a package called disk_util that will contain our function, which we will call get_disk_free_space as shown here:


    Requires Free Membership to View

CREATE OR REPLACE PACKAGE disk_util AS FUNCTION get_disk_free_space (root_path IN VARCHAR2, sectors_per_cluster OUT PLS_INTEGER, bytes_per_sector OUT PLS_INTEGER, number_of_free_clusters OUT PLS_INTEGER, total_number_of_clusters OUT PLS_INTEGER) RETURN PLS_INTEGER; PRAGMA RESTRICT_REFERENCES (get_disk_free_space, WNPS, RNPS, WNDS, RNDS); END disk_util;

All the magic is in the package body, which uses the EXTERNAL clause rather than a BEGIN..END block. This clause is where we define the interface between PL/SQL and the external routine:


 	CREATE OR REPLACE PACKAGE BODY disk_util
 	AS
 	     FUNCTION get_disk_free_space
 		(root_path IN VARCHAR2,
 		sectors_per_cluster OUT PLS_INTEGER,
 		bytes_per_sector OUT PLS_INTEGER,
 		number_of_free_clusters OUT PLS_INTEGER,
 		total_number_of_clusters OUT PLS_INTEGER)
 	     RETURN PLS_INTEGER
 	     IS EXTERNAL
 		LIBRARY nt_kernel	-- our library (defined previously)
 		NAME "GetDiskFreeSpaceA"-- name of function in kernel32.dll
 		LANGUAGE C		-- external routine is written in C
 		CALLING STANDARD PASCAL  -- uses Pascal parameter convention
 		PARAMETERS	      -- map PL/SQL to C parameters by position
 			(root_path STRING,
 			sectors_per_cluster BY REFERENCE LONG,
 			bytes_per_sector BY REFERENCE LONG,
 			number_of_free_clusters BY REFERENCE LONG,
 			total_number_of_clusters BY REFERENCE LONG,
 			RETURN LONG);-- "return code" indicating success or failure
 	END disk_util;
 

Assuming that the DBA has set up the environment to support external procedures, we can make an easy call to compute the disk space on the C: drive:


	 	SET SERVEROUTPUT ON SIZE 100000
        	DECLARE
        	     lroot_path VARCHAR2(3) := 'C: ';	-- look at C drive
        	     lsectors_per_cluster PLS_INTEGER;
        	     lbytes_per_sector PLS_INTEGER;
        	     lnumber_of_free_clusters PLS_INTEGER;
        	     ltotal_number_of_clusters PLS_INTEGER;
        	     return_code PLS_INTEGER;
        	     free_meg REAL;
        	BEGIN
        	     /* Call the external procedure.  We ignore the return code in this simple example.*/
        	     return_code := disk_util.get_free_disk_space (lroot_path, lsectors_per_cluster,
lbytes_per_sector,lnumber_of_free_clusters, ltotal_number_of_clusters);
         	     /* Using the drive statistics that are returned from the external procedure, 
||compute the amount of free disk space.  Remember Megabytes = (Bytes / 1024 / 1024)
        	    */
        	    free_meg := lsector_per_cluster * lbytes_per_sector * lnumber_of_free_clusters / 1024 / 1024;
       
         	    DBMS_OUTPUT.PUT_LINE('free disk space, megabytes = '|| free_meg);
        	END;
 
On my machine, this fragment produces the following output:
 
	free disk space, megabytes = 214.53515625
 

Of course, you could put this computation in a named function or procedure, and even make it part of the disk_util package.

If you are interested in purchasing the book Oracle PL/SQL programming, order it at http://www.oreilly.com/catalog/oraclep2/


This was first published in February 2000

There are Comments. Add yours.

 
TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.