/** * Create a network file for the specified file * * @param params FileOpenParams * @param fid int * @param stid int * @param did int * @param create boolean * @param dir boolean * @exception IOException * @exception FileNotFoundException */ public NetworkFile openFile( FileOpenParams params, int fid, int stid, int did, boolean create, boolean dir) throws IOException, FileNotFoundException { // Split the file name to get the name only String[] paths = FileName.splitPath(params.getPath()); String name = paths[1]; if (params.isStream()) name = name + params.getStreamName(); // Find, or create, the file state for the file/directory FileState fstate = m_stateCache.findFileState(params.getFullPath(), true); fstate.setExpiryTime(System.currentTimeMillis() + m_stateCache.getFileStateExpireInterval()); // Check if the file is a directory DBNetworkFile netFile = null; if (dir == false) { // Create the network file and associated file segment CachedNetworkFile cacheFile = createNetworkFile(fstate, params, name, fid, stid, did); netFile = cacheFile; // Check if the file is being opened for sequential access and the data has not yet been // loaded FileSegment fileSeg = cacheFile.getFileSegment(); if (create == true || params.isOverwrite() == true) { // Indicate that the file data is available, this is a new file or the existing file is // being // overwritten so there is no data to load. fileSeg.setStatus(FileSegmentInfo.Available); } else if (params.isSequentialAccessOnly() && fileSeg.isDataLoading() == false) { synchronized (cacheFile.getFileState()) { // Create the temporary file cacheFile.openFile(create); cacheFile.closeFile(); // Queue a file data load request if (fileSeg.isDataLoading() == false) queueFileRequest( new SingleFileRequest( FileRequest.LOAD, cacheFile.getFileId(), cacheFile.getStreamId(), fileSeg.getInfo(), cacheFile.getFullName(), fstate)); } // DEBUG if (Debug.EnableInfo && hasDebug()) Debug.println( "ObjIdLoader Queued file load, SEQUENTIAL access, file=" + cacheFile.getFullName()); } } else { // Create a placeholder network file for the directory netFile = new DirectoryNetworkFile(name, fid, did, m_stateCache.getFileStateProxy(fstate)); // Debug if (Debug.EnableInfo && hasDebug()) Debug.println("ObjIdLoader.openFile() DIR name=" + name + ", state=" + fstate); } // Return the network file return netFile; }
/** * Create a file segment to load/save the file data * * @param state FileState * @param params FileOpenParams * @param fname String * @param fid int * @param stid int * @param did int * @return CachedNetworkFile * @exception IOException */ private final CachedNetworkFile createNetworkFile( FileState state, FileOpenParams params, String fname, int fid, int stid, int did) throws IOException { // The file state is used to synchronize the creation of the file segment as there may be other // sessions opening the file at the same time. We have to be careful that only one thread // creates the // file segment. FileSegment fileSeg = null; CachedNetworkFile netFile = null; synchronized (state) { // Check if the file segment has been attached to the file state FileSegmentInfo fileSegInfo = (FileSegmentInfo) state.findAttribute(DBFileSegmentInfo); if (fileSegInfo == null) { // Check if we need to create a new temporary sub-drectory if (m_tempCount++ >= m_tempMax) createNewTempDirectory(); // Create a unique temporary file name StringBuffer tempName = new StringBuffer(); tempName.append(getTempFilePrefix()); tempName.append(fid); if (stid > 0) { tempName.append("_"); tempName.append(stid); // DEBUG if (Debug.EnableInfo && hasDebug()) Debug.println("## Temp file for stream ##"); } tempName.append(".tmp"); // Create a new file segment fileSegInfo = new FileSegmentInfo(); fileSeg = FileSegment.createSegment( fileSegInfo, tempName.toString(), m_curTempDir, params.isReadOnlyAccess() == false); // Add the segment to the file state cache state.addAttribute(DBFileSegmentInfo, fileSegInfo); // Check if the file is zero length, if so then set the file segment state to indicate it is // available DBFileInfo finfo = (DBFileInfo) state.findAttribute(FileState.FileInformation); if (finfo != null && finfo.getSize() == 0) fileSeg.setStatus(FileSegmentInfo.Available); } else { // Create the file segment to map to the existing temporary file fileSeg = new FileSegment(fileSegInfo, params.isReadOnlyAccess() == false); // Check if the temporary file exists, if not then create it File tempFile = new File(fileSeg.getTemporaryFile()); if (tempFile.exists() == false) { // Create the temporary file tempFile.createNewFile(); // Reset the file segment state to indicate a file load is required fileSeg.setStatus(FileSegmentInfo.Initial); } } // Create the new network file netFile = new CachedNetworkFile( fname, fid, stid, did, m_stateCache.getFileStateProxy(state), fileSeg, this); netFile.setGrantedAccess( params.isReadOnlyAccess() ? NetworkFile.READONLY : NetworkFile.READWRITE); netFile.setSequentialOnly(params.isSequentialAccessOnly()); netFile.setAttributes(params.getAttributes()); netFile.setFullName(params.getPath()); if (stid != 0) netFile.setStreamName(params.getStreamName()); } // Return the network file return netFile; }