Source Code Cross Referenced for FileChannel.java in  » Scripting » jacl » tcl » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * FileChannel.java --
003:         *
004:         * Copyright (c) 1997 Sun Microsystems, Inc.
005:         *
006:         * See the file "license.terms" for information on usage and
007:         * redistribution of this file, and for a DISCLAIMER OF ALL
008:         * WARRANTIES.
009:         * 
010:         * RCS: @(#) $Id: FileChannel.java,v 1.22 2006/07/11 09:10:44 mdejong Exp $
011:         *
012:         */
013:
014:        package tcl.lang;
015:
016:        import java.util.*;
017:        import java.io.*;
018:
019:        /**
020:         * Subclass of the abstract class Channel.  It implements all of the 
021:         * methods to perform read, write, open, close, etc on a file.
022:         */
023:
024:        class FileChannel extends Channel {
025:
026:            /**
027:             * The file needs to have a file pointer that can be moved randomly
028:             * within the file.  The RandomAccessFile is the only java.io class
029:             * that allows this behavior.
030:             */
031:
032:            private RandomAccessFile file = null;
033:
034:            /**
035:             * Open a file with the read/write permissions determined by modeFlags.
036:             * This method must be called before any other methods will function
037:             * properly.
038:             *
039:             * @param interp currrent interpreter.
040:             * @param fileName the absolute path or name of file in the current 
041:             *                 directory to open
042:             * @param modeFlags modes used to open a file for reading, writing, etc
043:             * @return the channelId of the file.
044:             * @exception TclException is thrown when the modeFlags try to open
045:             *                a file it does not have permission for or if the
046:             *                file dosent exist and CREAT wasnt specified.
047:             * @exception IOException is thrown when an IO error occurs that was not
048:             *                correctly tested for.  Most cases should be caught.
049:             */
050:
051:            String open(Interp interp, String fileName, int modeFlags)
052:                    throws IOException, TclException {
053:
054:                mode = modeFlags;
055:                File fileObj = FileUtil.getNewFileObj(interp, fileName);
056:
057:                // Raise error if file exists and both CREAT and EXCL are set
058:
059:                if (((modeFlags & TclIO.CREAT) != 0)
060:                        && ((modeFlags & TclIO.EXCL) != 0) && fileObj.exists()) {
061:                    throw new TclException(interp, "couldn't open \""
062:                            + fileName + "\": file exists");
063:                }
064:
065:                if (((modeFlags & TclIO.CREAT) != 0) && !fileObj.exists()) {
066:                    // Creates the file and closes it so it may be
067:                    // reopened with the correct permissions. (w, w+, a+)
068:
069:                    file = new RandomAccessFile(fileObj, "rw");
070:                    file.close();
071:                }
072:
073:                if ((modeFlags & TclIO.RDWR) != 0) {
074:                    // Opens file (r+), error if file does not exist.
075:
076:                    checkFileExists(interp, fileObj);
077:                    checkReadWritePerm(interp, fileObj, 0);
078:
079:                    if (fileObj.isDirectory()) {
080:                        throw new TclException(interp, "couldn't open \""
081:                                + fileName
082:                                + "\": illegal operation on a directory");
083:                    }
084:
085:                    file = new RandomAccessFile(fileObj, "rw");
086:
087:                } else if ((modeFlags & TclIO.RDONLY) != 0) {
088:                    // Opens file (r), error if file does not exist.
089:
090:                    checkFileExists(interp, fileObj);
091:                    checkReadWritePerm(interp, fileObj, -1);
092:
093:                    if (fileObj.isDirectory()) {
094:                        throw new TclException(interp, "couldn't open \""
095:                                + fileName
096:                                + "\": illegal operation on a directory");
097:                    }
098:
099:                    file = new RandomAccessFile(fileObj, "r");
100:
101:                } else if ((modeFlags & TclIO.WRONLY) != 0) {
102:                    // Opens file (a), error if dosent exist.
103:
104:                    checkFileExists(interp, fileObj);
105:                    checkReadWritePerm(interp, fileObj, 1);
106:
107:                    if (fileObj.isDirectory()) {
108:                        throw new TclException(interp, "couldn't open \""
109:                                + fileName
110:                                + "\": illegal operation on a directory");
111:                    }
112:
113:                    // Currently there is a limitation in the Java API.
114:                    // A file can only be opened for read OR read-write.
115:                    // Therefore if the file is write only, Java cannot
116:                    // open the file.  Throw an error indicating this
117:                    // limitation.
118:
119:                    if (!fileObj.canRead()) {
120:                        throw new TclException(
121:                                interp,
122:                                "Java IO limitation: Cannot open a file "
123:                                        + "that has only write permissions set.");
124:                    }
125:                    file = new RandomAccessFile(fileObj, "rw");
126:
127:                } else {
128:                    throw new TclRuntimeError(
129:                            "FileChannel.java: invalid mode value");
130:                }
131:
132:                // If we are appending, move the file pointer to EOF.
133:
134:                if ((modeFlags & TclIO.APPEND) != 0) {
135:                    file.seek(file.length());
136:                }
137:
138:                // Truncate file to zero length, this has to be done after
139:                // opening the file so that it will not fail even when another
140:                // handle to this same file is also open.
141:
142:                if ((modeFlags & TclIO.TRUNC) != 0) {
143:                    java.nio.channels.FileChannel chan = file.getChannel();
144:                    chan.truncate(0);
145:                }
146:
147:                // In standard Tcl fashion, set the channelId to be "file" + the
148:                // value of the current FileDescriptor.
149:
150:                String fName = TclIO.getNextDescriptor(interp, "file");
151:                setChanName(fName);
152:                return fName;
153:            }
154:
155:            /**
156:             * Close the file.  The file MUST be open or a TclRuntimeError
157:             * is thrown.
158:             */
159:
160:            void close() throws IOException {
161:                if (file == null) {
162:                    throw new TclRuntimeError(
163:                            "FileChannel.close(): null file object");
164:                }
165:
166:                // Invoke super.close() first since it might write an eof char
167:                try {
168:                    super .close();
169:                } finally {
170:                    file.close();
171:                    file = null;
172:                }
173:            }
174:
175:            /**
176:             * Move the file pointer internal to the RandomAccessFile object. 
177:             * The file MUST be open or a TclRuntimeError is thrown.
178:             * 
179:             * @param offset The number of bytes to move the file pointer.
180:             * @param inmode to begin incrementing the file pointer; beginning,
181:             * current, or end of the file.
182:             */
183:
184:            void seek(Interp interp, long offset, int inmode)
185:                    throws IOException, TclException {
186:
187:                if (file == null) {
188:                    throw new TclRuntimeError(
189:                            "FileChannel.seek(): null file object");
190:                }
191:
192:                //FIXME: Disallow seek on dead channels (raise TclPosixException ??)
193:                //if (CheckForDeadChannel(NULL, statePtr)) {
194:                //    return Tcl_LongAsWide(-1);
195:                //}
196:
197:                // Compute how much input and output is buffered. If both input and
198:                // output is buffered, cannot compute the current position.
199:
200:                int inputBuffered = getNumBufferedInputBytes();
201:                int outputBuffered = getNumBufferedOutputBytes();
202:
203:                if ((inputBuffered != 0) && (outputBuffered != 0)) {
204:                    throw new TclPosixException(interp,
205:                            TclPosixException.EFAULT, true,
206:                            "error during seek on \"" + getChanName() + "\"");
207:                }
208:
209:                // If we are seeking relative to the current position, compute the
210:                // corrected offset taking into account the amount of unread input.
211:
212:                if (inmode == TclIO.SEEK_CUR) {
213:                    offset -= inputBuffered;
214:                }
215:
216:                // The seekReset method will discard queued input and
217:                // reset flags like EOF and BLOCKED.
218:
219:                if (input != null) {
220:                    input.seekReset();
221:                }
222:
223:                // FIXME: Next block is disabled since non-blocking is not implemented.
224:                // If the channel is in asynchronous output mode, switch it back
225:                // to synchronous mode and cancel any async flush that may be
226:                // scheduled. After the flush, the channel will be put back into
227:                // asynchronous output mode.
228:
229:                boolean wasAsync = false;
230:                if (false && !getBlocking()) {
231:                    wasAsync = true;
232:                    setBlocking(true);
233:                    if (isBgFlushScheduled()) {
234:                        //scheduleBgFlush();
235:                    }
236:                }
237:
238:                // If there is data buffered in curOut then mark the
239:                // channel as ready to flush before invoking flushChannel.
240:
241:                if (output != null) {
242:                    output.seekCheckBuferReady();
243:                }
244:
245:                // If the flush fails we cannot recover the original position. In
246:                // that case the seek is not attempted because we do not know where
247:                // the access position is - instead we return the error. FlushChannel
248:                // has already called Tcl_SetErrno() to report the error upwards.
249:                // If the flush succeeds we do the seek also.
250:
251:                if (output != null && output.flushChannel(null, false) != 0) {
252:                    // FIXME: IS this the proper action to take on error?
253:                    throw new IOException("flush error while seeking");
254:                } else {
255:                    // Now seek to the new position in the channel as requested by the
256:                    // caller.
257:
258:                    long actual_offset;
259:
260:                    switch (inmode) {
261:                    case TclIO.SEEK_SET: {
262:                        actual_offset = offset;
263:                        break;
264:                    }
265:                    case TclIO.SEEK_CUR: {
266:                        actual_offset = file.getFilePointer() + offset;
267:                        break;
268:                    }
269:                    case TclIO.SEEK_END: {
270:                        actual_offset = file.length() + offset;
271:                        break;
272:                    }
273:                    default: {
274:                        throw new TclRuntimeError("invalid seek mode");
275:                    }
276:                    }
277:
278:                    // A negative offset to seek() would raise an IOException, but
279:                    // we want to raise an invalid argument error instead
280:
281:                    if (actual_offset < 0) {
282:                        throw new TclPosixException(interp,
283:                                TclPosixException.EINVAL, true,
284:                                "error during seek on \"" + getChanName()
285:                                        + "\"");
286:                    }
287:
288:                    file.seek(actual_offset);
289:                }
290:
291:                // Restore to nonblocking mode if that was the previous behavior.
292:                //
293:                // NOTE: Even if there was an async flush active we do not restore
294:                // it now because we already flushed all the queued output, above.
295:
296:                if (wasAsync) {
297:                    setBlocking(false);
298:                }
299:            }
300:
301:            /**
302:             * Tcl_Tell -> tell
303:             *
304:             * Return the current offset of the file pointer in number of bytes from 
305:             * the beginning of the file.  The file MUST be open or a TclRuntimeError
306:             * is thrown.
307:             *
308:             * @return The current value of the file pointer.
309:             */
310:
311:            long tell() throws IOException {
312:                if (file == null) {
313:                    throw new TclRuntimeError(
314:                            "FileChannel.tell(): null file object");
315:                }
316:                int inputBuffered = getNumBufferedInputBytes();
317:                int outputBuffered = getNumBufferedOutputBytes();
318:
319:                if ((inputBuffered != 0) && (outputBuffered != 0)) {
320:                    // FIXME: Posix error EFAULT ?
321:                    return -1;
322:                }
323:                long curPos = file.getFilePointer();
324:                if (curPos == -1) {
325:                    // FIXME: Set errno here?
326:                    return -1;
327:                }
328:                if (inputBuffered != 0) {
329:                    return curPos - inputBuffered;
330:                }
331:                return curPos + outputBuffered;
332:            }
333:
334:            /**
335:             * If the file dosent exist then a TclExcpetion is thrown. 
336:             *
337:             * @param interp currrent interpreter.
338:             * @param fileObj a java.io.File object of the file for this channel.
339:             */
340:
341:            private void checkFileExists(Interp interp, File fileObj)
342:                    throws TclException {
343:                if (!fileObj.exists()) {
344:                    throw new TclPosixException(interp,
345:                            TclPosixException.ENOENT, true, "couldn't open \""
346:                                    + fileObj.getName() + "\"");
347:                }
348:            }
349:
350:            /**
351:             * Checks the read/write permissions on the File object.  If inmode is less
352:             * than 0 it checks for read permissions, if mode greater than 0 it checks
353:             * for write permissions, and if it equals 0 then it checks both.
354:             *
355:             * @param interp currrent interpreter.
356:             * @param fileObj a java.io.File object of the file for this channel.
357:             * @param inmode what permissions to check for.
358:             */
359:
360:            private void checkReadWritePerm(Interp interp, File fileObj,
361:                    int inmode) throws TclException {
362:                boolean error = false;
363:
364:                if (inmode <= 0) {
365:                    if (!fileObj.canRead()) {
366:                        error = true;
367:                    }
368:                }
369:                if (inmode >= 0) {
370:                    if (!fileObj.canWrite()) {
371:                        error = true;
372:                    }
373:                }
374:                if (error) {
375:                    throw new TclPosixException(interp,
376:                            TclPosixException.EACCES, true, "couldn't open \""
377:                                    + fileObj.getName() + "\"");
378:                }
379:            }
380:
381:            String getChanType() {
382:                return "file";
383:            }
384:
385:            protected InputStream getInputStream() throws IOException {
386:                return new FileInputStream(file.getFD());
387:            }
388:
389:            protected OutputStream getOutputStream() throws IOException {
390:                return new FileOutputStream(file.getFD());
391:            }
392:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.