📄 ch4.htm
字号:
give you a sophisticated system of security layers. At the topof this security hierarchy is protection for the local file system.After all, the most prevalent methods for a virus to inflict painon its victim is to destroy his or her file system. Consequently,protection of the file system where the applet is running is paramount.<P>A Java environment enforces a security policy through its securitymanager. This is implemented as an object through the SecurityManagerclass and is created once and only once by a browser at startup.Once established, a SecurityManager cannot be changed or replaced.The reasons for this are obvious. If a rogue applet can modifythe SecurityManager object, then it can simply remove all accessrestrictions and wield unlimited power over your hard disk. However,it is possible to get a reference to the SecurityManager throughthe System object's <TT>getSecurityManager()</TT>method. Once obtained, methods can be applied on the object tosee what security constraints are currently being applied.<P>The strictness of a security policy depends on the runtime Javaenvironment. Netscape Navigator, for example, cannot perform anyfile operations. The simple File class example in the previoussection causes a security violation. This occurs when the File<TT>exists()</TT> method is invoked,which is the first file operation in the code (the File constructorsimply associates the String name with the object).<P>Sun's HotJava browser allows some file operations on the clientrunning an applet. Note that where the applet is loaded from isimportant. The client is the site running the applet; the serveris where the applet was loaded from. The security that concernsJava the most is that of the client site. In Hot Java, the operationsallowed on the client are based on the concept of <I>access controllists</I>. By default, any file not covered in the list cannotbe accessed in any fashion, including the simple File <TT>exists()</TT>operation. The access control list can be found in the propertiesfile of the .hotjava directory located under the parent.<P>File security is even weaker for the appletviewer program thatprogrammers can use to test an applet. In this environment, mostfile operations are allowed for applets loaded from the client.Some file operations performed by applets loaded from a serverover the network are also permitted. Standalone Java applicationshave no file security. If a sophisticated Java application isbeing developed, such as over an internal corporate network, itprobably would be best to create a subclass of SecurityManagerto set up a security policy appropriate for that environment.<P>When a file operation violates a security policy, a SecurityExceptionobject is thrown. This can be caught by the program to preventabnormal termination.<H3><A NAME="IOExceptions">I/O Exceptions</A></H3><P>Besides thrown SecurityException objects, Java I/O programs needto be concerned with handling other exceptions. In particular,they need to catch IOException objects that are thrown. The IOExceptionclass embraces the category of errors related to input/outputoperations. Many of the methods in the java.io package throw IOExceptionobjects that must be caught. The typical structure of code thatperforms I/O operations is, therefore, as follows:<BLOCKQUOTE><TT>try {<BR> // IO operations<BR>}<BR>catch (IOException e) {<BR> // Handle the error<BR>}</TT></BLOCKQUOTE><P>Two subclasses of IOException are noteworthy. A FileNotFoundExceptionobject is thrown when there is an attempt to open a file thatdoesn't exist. For example, the constructor for the FileInputStreamclass tries to open the file specified in its parameter. If itcannot do so, an object of class FileNotFoundException is thrown.<P>Another notable subclass of IOException is EOFException, whichtypically occurs in read operations when an end of file has beenreached. This indicates that there are no more bytes to be read.<H3><A NAME="InputStreamClasses">InputStream Classes</A></H3><P>Figure 4.7 illustrates the class hierarchy that descends fromthe InputStream class. InputStream is an abstract class that definesthe basic operations that must be implemented by its subclasses.The most noteworthy of these is the <TT>read()</TT>method. This is used to read in bytes one at a time or into abyte array. The System.in variable, which represents that standardinput stream, is based on the InputStream class and is now usedto illustrate the <TT>read()</TT>method:<P><A HREF="f4-7.gif" ><B>Figure 4.7 :</B><I> Input stream classes</I></A><BLOCKQUOTE><TT>try {<BR> int b;<BR> b = System.in.read();<BR>}<BR>catch (IOException e) {<BR> // Handle any exception…<BR>}</TT></BLOCKQUOTE><P>This example reads in a byte that is, confusingly, converted toan integer by the <TT>read()</TT>method. The method returns <TT>-1</TT>if there is no input to be read. For many subclasses of InputStream,an EOFException object is thrown in these circumstances.<P>Table 4.2 lists other notable methods of the abstract InputStreamclass.<BR><P><CENTER><B>Table 4.2. Notable InputStream methods.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=124><I>Method</I></TD><TD WIDTH=409><I>Description</I></TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>available</TT></TD><TD WIDTH=409>A non-blocking way to find out number of bytes available to read.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>Close</TT></TD><TD WIDTH=409>Closes the input stream.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>mark</TT></TD><TD WIDTH=409>Marks the current stream position.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>read</TT></TD><TD WIDTH=409>Reads a byte or array of bytes.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>reset</TT></TD><TD WIDTH=409>Resets stream to last marked position.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>skip</TT></TD><TD WIDTH=409>Skips over specified number of input bytes.</TD></TR></TABLE></CENTER><P><H4>FilterInputStream classes</H4><P>The FilterInputStream class is at the top of a branch of the InputStreamhierarchy that can be used to implement some very powerful operations.In particular, this class is used to chain a series of FilterInputStreamclasses so that one stream can process data before passing it"up" to the next stream. This chaining technique isexcellent to use when encapsulating classes that interact withstreams at a lower level (such as bytes) into streams that readin data at a higher level, such as Strings. The following exampleillustrates how this works.<P>As seen in the previous overview of the InputStream class, theSystem.in object reads data in a byte at a time. This will proveto be cumbersome for many standard input operations that typicallywant to work on String objects. Fortunately, FilterInputStreamclasses make it easy to abstract this byte-level functionalityinto a higher and more usable interface. The code in Listing 4.6takes the System.in object and creates a DataInputStream objectthat can be used to read in a String of text delimited by a newlineor EOF. This is then sent to the System.out object, which printsthe string to the standard output stream.<HR><BLOCKQUOTE><B>Listing 4.6. Chaining Input Stream classes.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>try {<BR> // Createthe data input stream...<BR> DataInputStreamdis =<BR> newDataInputStream(<BR> newBufferedInputStream(System.in));<BR> // Readin a line of text...<BR> String s= dis.readLine();<BR> // Sendit to standard output...<BR> System.out.println(s);<BR> }<BR> // Handle any exceptions causedby the process...<BR> catch (IOException e) {<BR> // Justprint out the error...<BR> System.out.println(e.getMessage());<BR> }</TT></BLOCKQUOTE><P>The first line inside the <TT>try</TT>clause is full of material; the innermost part of the clause introducesthe BufferedInputStream class:<BLOCKQUOTE><TT>new BufferedInputStream(System.in)</TT></BLOCKQUOTE><P>This subclass of FilterInputStream simply allows the reading inof data more efficiently. Reading a file so that every byte requestrequires a new input read is very slow. The BufferedInputStreamclass reads data into a buffer in a series of large chunks. Thisprevents each request for a byte of data resulting in a read fromthe underlying input stream, such as a file or network read. Ifthe BufferedInputStream already has the data in the buffer, itcan return the data directly from its memory cache. This is alsouseful for operations that require movement back and forth ina stream, such as a "push back" of an unneeded byte.Since this class will improve the efficiency of input stream operations,it should be used liberally.<P>Once the BufferedInputStream object is created, it is used asthe constructor for a DataInputStream object:<BLOCKQUOTE><TT>DataInputStream dis =<BR> new DataInputStream(<BR> newBufferedInputStream(System.in));</TT></BLOCKQUOTE><P>This code means that the DataInputStream object's request forinput is actually made to a BufferedInputStream object. This objectin turn makes its requests for input to the System.in object (whichis based on InputStream) when it needs more data.<P>The code can now use DataInputStream methods, such as <TT>readLine()</TT>,to hide the underlying request of data at a byte-by-byte level.The DataInputStream methods return the data formatted in a datatype that the user needs. In this case, <TT>readLine()</TT>reads in a String of text delimited by a new Line (a carriagereturn/line feed, or EOF). The delimiter is not included in thestream.<P>The DataInputStream class supports over a dozen data type operations,as listed in Table 4.3. These include most of the basic data typessupported from Java, ranging from a single byte to an integerto a floating point number to a full-text String in Unicode format.The DataInputStream class is an implementation of the DataInputstream interface, which defines the data type methods that needto be supported.<BR><P><CENTER><B>Table 4.3. Data-type reads supported by DataInputStream.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=186><I>Method</I></TD><TD WIDTH=306><I>Description</I></TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>read</TT></TD><TD WIDTH=306>Reads data into byte array.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readBoolean</TT></TD><TD WIDTH=306>Reads a boolean.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readByte</TT></TD><TD WIDTH=306>Reads an 8-bit byte.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readChar</TT></TD><TD WIDTH=306>Reads a 16-bit char.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readDouble</TT></TD><TD WIDTH=306>Reads a 64-bit double number.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readFloat</TT></TD><TD WIDTH=306>Reads a 32-bit floating point number.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readInt</TT></TD><TD WIDTH=306>Reads a 32-bit integer.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readLine</TT></TD><TD WIDTH=306>Reads String terminated by newline or EOF.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readLong</TT></TD><TD WIDTH=306>Reads a 64-bit long.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readShort</TT></TD><TD WIDTH=306>Reads a 16-bit short.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readUTF</TT></TD><TD WIDTH=306>Reads a Unicode formatted String.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readUnsignedByte</TT></TD><TD WIDTH=306>Reads an unsigned byte.</TD></TR><TR VALIGN=TOP><TD WIDTH=186><TT>readUnsignedShort</TT></TD><TD WIDTH=306>Reads an unsigned 16-bit short.</TD></TR></TABLE></CENTER><P><P>From the powerful chaining operation supported by FilterInputStream,it's easy to imagine interesting new possible classes. For example,a WordProcessStream could be written to read paragraphs and imagesinto a word processing application.<P>Two other FilterInputStream classes are worth mentioning. TheLineNumberInputStream class associates the data streams with linenumbers. This means that the class supports such operations as<TT>setLineNumber()</TT> and <TT>getLineNumber()</TT>.The PushBackInputStream class is used for the kind of operationsthat parsers typically perform. Parsers need methods such as <TT>unread()</TT>,which pushes a character back into a stream. This kind of operationis needed when a token has been identified by the parser.<H4>Other InputStream classes</H4><P>Although the FilterInputStream classes are the most powerful partof the InputStream hierarchy, other classes are also useful. Ifapplets read from a file, an instance of the FileInputStream classwill probably be used. It includes the same operations as itssuperclass, InputStream. Therefore, it can be used to pass datato FilterInputStream classes, as in the previous section's example.Listin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -