?? openfile.cc
字號:
// openfile.cc // Routines to manage an open Nachos file. As in UNIX, a// file must be open before we can read or write to it.// Once we're all done, we can close it (in Nachos, by deleting// the OpenFile data structure).//// Also as in UNIX, for convenience, we keep the file header in// memory while the file is open.//// Copyright (c) 1992-1993 The Regents of the University of California.// All rights reserved. See copyright.h for copyright notice and limitation // of liability and disclaimer of warranty provisions.#include "copyright.h"#include "filehdr.h"#include "openfile.h"#include "system.h"#ifdef HOST_SPARC#include <strings.h>#endif//----------------------------------------------------------------------// OpenFile::OpenFile// Open a Nachos file for reading and writing. Bring the file header// into memory while the file is open.//// "sector" -- the location on disk of the file header for this file//----------------------------------------------------------------------OpenFile::OpenFile(int sector){ hdr = new FileHeader; hdr->FetchFrom(sector); seekPosition = 0;}//----------------------------------------------------------------------// OpenFile::~OpenFile// Close a Nachos file, de-allocating any in-memory data structures.//----------------------------------------------------------------------OpenFile::~OpenFile(){ delete hdr;}//----------------------------------------------------------------------// OpenFile::Seek// Change the current location within the open file -- the point at// which the next Read or Write will start from.//// "position" -- the location within the file for the next Read/Write//----------------------------------------------------------------------voidOpenFile::Seek(int position){ seekPosition = position;} //----------------------------------------------------------------------// OpenFile::Read/Write// Read/write a portion of a file, starting from seekPosition.// Return the number of bytes actually written or read, and as a// side effect, increment the current position within the file.//// Implemented using the more primitive ReadAt/WriteAt.//// "into" -- the buffer to contain the data to be read from disk // "from" -- the buffer containing the data to be written to disk // "numBytes" -- the number of bytes to transfer//----------------------------------------------------------------------intOpenFile::Read(char *into, int numBytes){ int result = ReadAt(into, numBytes, seekPosition); seekPosition += result; return result;}intOpenFile::Write(char *into, int numBytes){ int result = WriteAt(into, numBytes, seekPosition); seekPosition += result; return result;}//----------------------------------------------------------------------// OpenFile::ReadAt/WriteAt// Read/write a portion of a file, starting at "position".// Return the number of bytes actually written or read, but has// no side effects (except that Write modifies the file, of course).//// There is no guarantee the request starts or ends on an even disk sector// boundary; however the disk only knows how to read/write a whole disk// sector at a time. Thus://// For ReadAt:// We read in all of the full or partial sectors that are part of the// request, but we only copy the part we are interested in.// For WriteAt:// We must first read in any sectors that will be partially written,// so that we don't overwrite the unmodified portion. We then copy// in the data that will be modified, and write back all the full// or partial sectors that are part of the request.//// "into" -- the buffer to contain the data to be read from disk // "from" -- the buffer containing the data to be written to disk // "numBytes" -- the number of bytes to transfer// "position" -- the offset within the file of the first byte to be// read/written//----------------------------------------------------------------------intOpenFile::ReadAt(char *into, int numBytes, int position){ int fileLength = hdr->FileLength(); int i, firstSector, lastSector, numSectors; char *buf; if ((numBytes <= 0) || (position >= fileLength)) return 0; // check request if ((position + numBytes) > fileLength) numBytes = fileLength - position; DEBUG('f', "Reading %d bytes at %d, from file of length %d.\n", numBytes, position, fileLength); firstSector = divRoundDown(position, SectorSize); lastSector = divRoundDown(position + numBytes - 1, SectorSize); numSectors = 1 + lastSector - firstSector; // read in all the full and partial sectors that we need buf = new char[numSectors * SectorSize]; for (i = firstSector; i <= lastSector; i++) synchDisk->ReadSector(hdr->ByteToSector(i * SectorSize), &buf[(i - firstSector) * SectorSize]); // copy the part we want bcopy(&buf[position - (firstSector * SectorSize)], into, numBytes); delete [] buf; return numBytes;}intOpenFile::WriteAt(char *from, int numBytes, int position){ int fileLength = hdr->FileLength(); int i, firstSector, lastSector, numSectors; bool firstAligned, lastAligned; char *buf; if ((numBytes <= 0) || (position >= fileLength)) return 0; // check request if ((position + numBytes) > fileLength) numBytes = fileLength - position; DEBUG('f', "Writing %d bytes at %d, from file of length %d.\n", numBytes, position, fileLength); firstSector = divRoundDown(position, SectorSize); lastSector = divRoundDown(position + numBytes - 1, SectorSize); numSectors = 1 + lastSector - firstSector; buf = new char[numSectors * SectorSize]; firstAligned = (position == (firstSector * SectorSize)); lastAligned = ((position + numBytes) == ((lastSector + 1) * SectorSize));// read in first and last sector, if they are to be partially modified if (!firstAligned) ReadAt(buf, SectorSize, firstSector * SectorSize); if (!lastAligned && ((firstSector != lastSector) || firstAligned)) ReadAt(&buf[(lastSector - firstSector) * SectorSize], SectorSize, lastSector * SectorSize); // copy in the bytes we want to change bcopy(from, &buf[position - (firstSector * SectorSize)], numBytes);// write modified sectors back for (i = firstSector; i <= lastSector; i++) synchDisk->WriteSector(hdr->ByteToSector(i * SectorSize), &buf[(i - firstSector) * SectorSize]); delete [] buf; return numBytes;}//----------------------------------------------------------------------// OpenFile::Length// Return the number of bytes in the file.//----------------------------------------------------------------------intOpenFile::Length() { return hdr->FileLength(); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -