home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / Packaging / Extract / Extract.java < prev    next >
Encoding:
Java Source  |  2000-05-04  |  10.9 KB  |  405 lines

  1. //
  2. // Extract.java
  3. //
  4. // This application demonstrates how to use the CabDecoder class to extract
  5. // files from, or list files in cabinets.
  6. //
  7. // (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  8. // All rights reserved 
  9. //
  10. import com.ms.util.cab.CabDecoder;
  11. import com.ms.util.cab.CabDecoderInterface;
  12. import com.ms.util.cab.CabFileEntry;
  13. import com.ms.util.cab.CabFolderEntry;
  14. import com.ms.util.cab.CabException;
  15. import java.io.*;
  16. import java.util.Enumeration;
  17. import java.util.Date;
  18.  
  19.  
  20. final class Extract implements CabDecoderInterface
  21. {
  22.     private String          cabinet_filename;
  23.     private String          output_directory;
  24.     private CabDecoder      cab_decoder;
  25.     private FileInputStream input;
  26.  
  27.  
  28.     private Extract(String filename)
  29.     {
  30.         cabinet_filename    = filename;
  31.     }
  32.  
  33.  
  34.     //
  35.     // Entrypoint
  36.     //
  37.     public static void main(String args[])
  38.     {
  39.         Extract extractor;
  40.         int     cab_filename_argnum;
  41.  
  42.         if (args.length < 1)
  43.         {
  44.             displayHelp();
  45.         }
  46.         else
  47.         {
  48.             String  cab_filename;
  49.             String  specified_output_directory;
  50.             boolean list_cabinet_only = false;
  51.  
  52.             if (args[0].equalsIgnoreCase("/V"))
  53.             {
  54.                 if (args.length < 2)
  55.                 {
  56.                     displayHelp();
  57.                     return;
  58.                 }
  59.  
  60.                 list_cabinet_only = true;
  61.                 cab_filename_argnum = 1;
  62.             }
  63.             else
  64.             {
  65.                 cab_filename_argnum = 0;
  66.             }
  67.  
  68.             cab_filename = args[cab_filename_argnum];
  69.  
  70.             if (args.length > cab_filename_argnum+1)
  71.                 specified_output_directory = args[cab_filename_argnum+1];
  72.             else
  73.                 specified_output_directory = null;
  74.  
  75.             //
  76.             // Need to create an object to pass to the CabDecoder class
  77.             //
  78.             extractor = new Extract(cab_filename);
  79.             
  80.             //
  81.             // If cabinet opened successfully
  82.             //
  83.             if (extractor.openCabinetForReading() == true)
  84.             {
  85.                 //
  86.                 // List cabinet contents, or extract, depending upon what
  87.                 // the user wanted
  88.                 //
  89.                 if (list_cabinet_only)
  90.                     extractor.listCabinet();
  91.                 else
  92.                     extractor.extractCabinet(specified_output_directory);
  93.                 
  94.                 //
  95.                 // Clean up
  96.                 //
  97.                 extractor.closeCabinet();
  98.             }
  99.         }
  100.     }
  101.  
  102.  
  103.     public InputStream openCabinet(String disk_name, String cabinet_name)
  104.     {
  105.         return null;
  106.     }
  107.  
  108.  
  109.     //
  110.     // Open the cabinet
  111.     //
  112.     // Returns whether the cabinet was opened successfully
  113.     //
  114.     private boolean openCabinetForReading()
  115.     {
  116.         try
  117.         {
  118.             input = new FileInputStream(cabinet_filename);
  119.         }
  120.         catch (FileNotFoundException fnf)
  121.         {
  122.             System.out.println("Cabinet not found: "+cabinet_filename);
  123.             return false;
  124.         }
  125.  
  126.         //
  127.         // If the cabinet header is corrupt, an exception will be thrown
  128.         //
  129.         try
  130.         {
  131.             cab_decoder = new CabDecoder(input, this);
  132.         }
  133.         catch (Exception e)
  134.         {
  135.             System.out.println("Error processing cabinet: "+e.getMessage());
  136.             try { input.close(); } catch (IOException closing_ioe) {}
  137.             return false;
  138.         }
  139.  
  140.         return true; // success
  141.     }
  142.  
  143.  
  144.     //
  145.     // Close the cabinet's input stream
  146.     //
  147.     private void closeCabinet()
  148.     {
  149.         try
  150.         {
  151.             input.close();
  152.         }
  153.         catch (IOException ioe)
  154.         {
  155.             System.out.println("IOException closing cabinet: "+ioe.getMessage());
  156.         }
  157.     }
  158.  
  159.  
  160.     //
  161.     // List the contents of the cabinet
  162.     //
  163.     private void listCabinet()
  164.     {
  165.         //
  166.         // Assume an 80 column display
  167.         //
  168.         System.out.println();
  169.         System.out.println("Listing files in cabinet '"+cabinet_filename+"':");
  170.         System.out.println();
  171.         System.out.println("File name                                 File size  Attr  File date");
  172.         System.out.println("----------------------------------------  ---------  ----  -----------------");
  173.  
  174.         //
  175.         // Enumerate the complete contents of the cabinet, including CabFolderEntry
  176.         // objects
  177.         //
  178.         Enumeration cab_contents = cab_decoder.entries(true);
  179.  
  180.         while (cab_contents.hasMoreElements())
  181.         {
  182.             Object entry;
  183.             
  184.             entry = cab_contents.nextElement();
  185.  
  186.             if (entry instanceof CabFolderEntry)
  187.             {
  188.                 CabFolderEntry folder = (CabFolderEntry) entry;
  189.  
  190.                 System.out.println();
  191.                 System.out.println(
  192.                     "FOLDER (" + folder.compressionToString() + " compression):"
  193.                 );
  194.             }
  195.             else if (entry instanceof CabFileEntry)
  196.             {
  197.                 CabFileEntry file = (CabFileEntry) entry;
  198.  
  199.                 //
  200.                 // Display file information in tabulated form.
  201.                 //
  202.                 // Use locale-specific date format
  203.                 //
  204.                 System.out.println(
  205.                     StringPad.padPostfix(file.getName(),42) +
  206.                     StringPad.padNumber(file.getSize(), 9) + "  " +
  207.                     cabFileEntryAttributesToString(file) + "  " + 
  208.                     file.getDate().toLocaleString()
  209.                 );
  210.             }
  211.             // ignore objects we don't know how to handle
  212.  
  213.         }
  214.     }
  215.  
  216.  
  217.     //
  218.     // Extract the cabinet
  219.     //
  220.     private void extractCabinet(String new_output_directory)
  221.     {
  222.         output_directory = new_output_directory;
  223.  
  224.         System.out.println();
  225.         System.out.println("Extracting files from cabinet '"+cabinet_filename+"':");
  226.  
  227.         //
  228.         // If an error occurs, an exception will be thrown
  229.         //
  230.         try
  231.         {
  232.             cab_decoder.extract();
  233.         }
  234.         catch (Exception e)
  235.         {
  236.             System.out.println("Error extracting cabinet: "+e.getMessage());
  237.         }
  238.     }
  239.  
  240.  
  241.     //
  242.     // Convert file attributes to a string
  243.     //
  244.     private static String cabFileEntryAttributesToString(CabFileEntry cffile)
  245.     {
  246.         return  (cffile.isReadOnly() ? "r" : "-") +
  247.                 (cffile.isArchive()  ? "a" : "-") +
  248.                 (cffile.isHidden()   ? "h" : "-") +
  249.                 (cffile.isSystem()   ? "s" : "-");
  250.     }
  251.  
  252.     
  253.     //
  254.     // Command-line help
  255.     //
  256.     private static void displayHelp()
  257.     {
  258.         System.out.println("Cabinet extract utility");
  259.         System.out.println();
  260.         System.out.println("Usage: extract [/V] <cabinet name>");
  261.         System.out.println();
  262.         System.out.println("       Use /V to list cabinet contents instead of extracting");
  263.     }
  264.  
  265.  
  266.     //
  267.     // Converts a filename which uses the backslash as the separator character,
  268.     // to use the local system's separator character
  269.     //
  270.     // This stage is necessary since cab files are stored using the backslash
  271.     // as the separator.
  272.     //
  273.     static String convertFilenameToSystemSeparator(String filename)
  274.     {
  275.         if (File.separatorChar != '\\')
  276.             return filename.replace('\\', File.separatorChar);
  277.         else
  278.             return filename;
  279.     }
  280.  
  281.     
  282.  
  283.     //
  284.     // Implements CabDecoderInterface
  285.     //
  286.     public boolean closeOutputStream(OutputStream output, CabFileEntry file, boolean success)
  287.     {
  288.         try
  289.         {
  290.             output.close();
  291.         }
  292.         catch (IOException ioe)
  293.         {
  294.             System.out.println("IOException closing output file "+file.getName());
  295.         }
  296.  
  297.         return true;
  298.     }
  299.  
  300.  
  301.     //
  302.     // Called for each file in the cabinet, when we're extracting
  303.     //
  304.     public OutputStream openOutputStream(CabFileEntry file)
  305.     {
  306.         File                output_file;
  307.         FileOutputStream    output_stream;
  308.         String              filename, complete_filename;
  309.  
  310.         // Convert filename to use local separator convention
  311.         filename = convertFilenameToSystemSeparator(file.getName());
  312.  
  313.         output_file = new File(filename);
  314.         
  315.         if (false && output_file.isAbsolute())
  316.         {
  317.             System.out.println(
  318.                 "  ** Not extracting file with absolute pathname: " + filename
  319.             );
  320.  
  321.             return null;
  322.         }
  323.  
  324.         // Display the (converted) filename
  325.         System.out.println("   " + file.getName());
  326.  
  327.         // Get the complete filename (with output directory prefix)
  328.         if (output_directory != null)
  329.             complete_filename = output_directory + File.separator + filename;
  330.         else
  331.             complete_filename = filename;
  332.  
  333.         // Open file for output
  334.         output_file = new File(complete_filename);
  335.  
  336.         try
  337.         {
  338.             output_stream   = new FileOutputStream(output_file);
  339.         }
  340.         catch (IOException ioe)
  341.         {
  342.             //
  343.             // Couldn't create the output stream; it could be that the
  344.             // directories don't exist for it, so create them and try again
  345.             //
  346.             String parent_dir_name = output_file.getParent();
  347.  
  348.             if (parent_dir_name == null)
  349.             {
  350.                 return null;
  351.             }
  352.             else
  353.             {
  354.                 File parent_dir = new File(parent_dir_name);
  355.                 
  356.                 if (parent_dir != null)
  357.                     parent_dir.mkdirs();
  358.             }
  359.  
  360.             try
  361.             {
  362.                 output_stream   = new FileOutputStream(output_file);
  363.             }
  364.             catch (IOException ioe2)
  365.             {
  366.                 System.out.println(
  367.                     "IOException opening output file " + complete_filename
  368.                 );
  369.  
  370.                 return null;
  371.             }
  372.         }
  373.  
  374.         return output_stream;
  375.     }
  376.  
  377.  
  378.     //
  379.     // For opening spanned cabinets
  380.     //
  381.     public InputStream openCabinet(String disk_name, String cabinet_name, int set_id)
  382.     {
  383.         return null;
  384.     }
  385.  
  386.  
  387.     //
  388.     // Don't want any reserved areas
  389.     //
  390.     public boolean reservedAreaData(int type, byte[] reserved_data, int reserved_data_size, byte[] other_data, int other_data_size)
  391.     {
  392.         return false;
  393.     }
  394.  
  395.  
  396.     //
  397.     // The cab decoder doesn't send any progress reports at this time
  398.     //
  399.     public Object progress(int progress_type, long val1, long val2, Object[] progress_data)
  400.     {
  401.         // return null for progress reports we don't know how to handle
  402.         return null;
  403.     }
  404. }
  405.