File and directory.


In  Working with Directories in Objective-C we looked at the NSFileManager, NSFileHandle and NSData Foundation Framework classes and discussed how the NSFileManager class in particular enables us to work with directories in Objective-C. In this chapter we move on from working with directories to covering the details of working with files using all three of these classes.

Creating an NSFileManager Instance

First we need to recap the steps necessary to create an instance of the NSFileManager class. As discussed in the previous chapter, the NSFileManager class contains a class method nameddefaultManager that is used to create an instance of the class. For example:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2. filemgr = [NSFileManager defaultManager];  

Checking if a File Exists

The NSFileManager class contains an instance method named fileExistsAtPath that checks whether a specified file already exists. The method takes as an argument an NSString object containing the path to file and returns a boolean YES or NO value indicating the presence or otherwise of that file:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2.   
  3. filemgr = [NSFileManager defaultManager];  
  4. if ([filemgr fileExistsAtPath: @"/tmp/myfile.txt" ] == YES)  
  5.         NSLog (@"File exists");  
  6. else  
  7.         NSLog (@"File not found");  

Comparing the Contents of Two Files

The contents of two files can be compared for equality using the contentsEqualAtPath method. This method takes as arguments the paths to the two files to be compared and returns a boolean YES or NO to indicate whether the file contents match:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2.   
  3. filemgr = [NSFileManager defaultManager];  
  4.   
  5. if ([filemgr contentsEqualAtPath: @"/tmp/myfile.txt" andPath: @"/tmp/sales.txt"] == YES)  
  6.         NSLog (@"File contents match");  
  7. else  
  8.         NSLog (@"File contents do not match");  

Checking if a File is Readable/Writable/Executable/Deletable

Most operating systems provide some level of file access control. These typically take the form of attributes that control the level of access to a file for each user or user group. As such, it is not a certainty that your program will have read or write access to a particular file, or the appropriate permissions to delete or execute it. The quickest way to find out if your program has a particular access permission is to use theisReadableFileAtPathisWritableFileAtPathisExecutableFileAtPath andisDeletableFileAtPath methods. Each method takes a single argument in the form of the path to the file to be checked and returns a boolean YES or NO result. For example, the following code excerpt checks to find out if a file is writable:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2.   
  3. filemgr = [NSFileManager defaultManager];  
  4.   
  5. if ([filemgr isWritableFileAtPath: @"/tmp/myfile.txt"]  == YES)  
  6.         NSLog (@"File is writable");  
  7. else  
  8.         NSLog (@"File is read only");  

To check for other access permissions simply substitute the corresponding method name in place ofisWritableFileAtPath in the above example.

Moving/Renaming a File

A file may be renamed (assuming adequate permissions) using the moveItemAtPath method. This method returns a boolean YES or NO result and takes as arguments the pathname for the file to be moved, the destination path and an optional NSError object into which information describing any errors encountered during the operation will be placed. If no error description information is required, this argument may be set to NULL. Note that if the destination file path already exists this operation will fail.

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2.   
  3. filemgr = [NSFileManager defaultManager];  
  4.   
  5. if ([filemgr moveItemAtPath: @"/tmp/myfile.txt" toPath: @"/tmp/newfile.txt" error: NULL]  == YES)  
  6.         NSLog (@"Move successful");  
  7. else  
  8.         NSLog (@"Move failed");  

Copying a File

File copying can be achieved using the copyItemAtPath method. As with themove method, this takes as arguments the source and destination pathnames and an optional NSError object. Success of the operation is indicated by the returned boolean value:

[plain]  view plain copy
  1. if ([filemgr copyItemAtPath: @"/tmp/myfile.txt" toPath: @"/Users/demo/newfile.txt" error: NULL]  == YES)  
  2.         NSLog (@"Copy successful");  
  3. else  
  4.         NSLog (@"Copy failed");  

Removing a File

The removeItemAtPath method removes the specified file from the file system. The method takes as arguments the pathname of the file to be removed and an optional NSError object. The success of the operation is, as usual, reported in the form of a boolean YES or NO return value:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2.   
  3. filemgr = [NSFileManager defaultManager];  
  4.   
  5. if ([filemgr removeItemAtPath: @"/tmp/myfile.txt" error: NULL]  == YES)  
  6.         NSLog (@"Remove successful");  
  7. else  
  8.         NSLog (@"Remove failed");  

Creating a Symbolic Link

A symbolic link to a particular file may be created using the createSymbolicLinkAtPath method. This takes arguments the path of the symbolic link, the path to the file to which the link is to refer and an optional NSError object. For example, the following code creates a symbolic link from /Users/demo/file1.txt that links to the pre-existing file/tmp/myfile.txt:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2.   
  3. filemgr = [NSFileManager defaultManager];  
  4.   
  5. if ([filemgr createSymbolicLinkAtPath: @"/Users/demo/file1.txt"   
  6.                 withDestinationPath: @"/tmp/myfile.txt" error: NULL]  == YES)  
  7.         NSLog (@"Remove successful");  
  8. else  
  9.         NSLog (@"Remove failed");  

Reading and Writing Files with NSFileManager

The NSFileManager class includes some basic file reading and writing capabilities. these capabilities are somewhat limited when compared to the options provided by the NSFileHandle class, but can be useful nonetheless.

Firstly, the contents of a file may be read and stored in an NSData object through the use of thecontentsAtPath method:

[plain]  view plain copy
  1. NSFileManager *filemgr;  
  2. NSData *databuffer;  
  3.   
  4. filemgr = [NSFileManager defaultManager];  
  5.   
  6. databuffer = [filemgr contentsAtPath: @"/tmp/myfile.txt" ];  

Having stored the contents of a file in an NSData object, that data may subsequently be written out to a new file using thecreateFileAtPath method:

[plain]  view plain copy
  1. databuffer = [filemgr contentsAtPath: @"/tmp/myfile.txt" ];  
  2.   
  3. [filemgr createFileAtPath: @"/tmp/newfile.txt" contents: databuffer attributes: nil];  

In the above example we have essentially copied the contents from an existing file to a new file. This, however, gives us no control over how much data is to be read or written and does not allow us to append data to the end of an existing file. If the file/tmp/newfile.txt in the above example had already existed it, and any data it contained, would have been overwritten by the contents of the source file. Clearly some more flexible mechanism is required. This is provided by the Foundation Framework in the form of theNSFileHandle class.

Working with Files using the NSFileHandle Class

The NSFileHandle class provides a range of methods designed to provide a more advanced mechanism for working with files. In addition to files, this class can also be used for working with devices and network sockets. In the following sections we will look at some of the more common uses for this class.

Creating an NSFileHandle Object

An NSFileHandle object can be created when opening a file for reading, writing or updating (reading and writing). This is achieved using thefileHandleForReadingAtPathfileHandleForWritingAtPath andfileHandleForUpdatingAtPath methods respectively. Having opened a file, it must subsequently be closed when we have finished working with it using thecloseFile method. If an attempt to open a file fails, for example because an attempt is made to open a non-existent file for reading, these methods returnnil.

For example, the following code excerpt opens a file for reading and writing and then closes it without actually doing anything to the file:

[plain]  view plain copy
  1. NSFileHandle *file;  
  2.   
  3. file = [NSFileHandle fileHandleForWritingAtPath: @"/tmp/myfile.txt"];  
  4.   
  5. if (file == nil)  
  6.         NSLog(@"Failed to open file");  
  7.   
  8. [file closeFile];  

NSFileHandle File Offsets and Seeking

NSFileHandle objects maintain a pointer to the current position in a file. This is referred to as theoffset. When a file is first opened the offset is set to 0 (the beginning of the file). This means that any read or write operations we perform using the NSFileHandle methods will take place at offset 0 in the file. To perform operations at different locations in a file (for example to append data to the end of the file) it is first necessary toseek to the required offset. For example to move the current offset to the end of the file, use theseekToEndOfFile method. Alternatively, seekToFileOffset allows you to specify the precise location in the file to which the offset is to be positioned. Finally, the current offset may be identified using theoffsetInFilemethod. In order to accommodate large files, the offset is stored in the form of an unsigned long long.

The following example opens a file for reading and then performs a number of method calls to move the offset to different positions, outputting the current offset after each move:

[plain]  view plain copy
  1. file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/myfile.txt"];  
  2.   
  3. if (file == nil)  
  4.         NSLog(@"Failed to open file");  
  5.   
  6. NSLog (@"Offset = %llu", [file offsetInFile]);  
  7.   
  8. [file seekToEndOfFile];  
  9.   
  10. NSLog (@"Offset = %llu", [file offsetInFile]);  
  11.   
  12. [file seekToFileOffset: 30];  
  13.   
  14. NSLog (@"Offset = %llu", [file offsetInFile]);  
  15.   
  16. [file closeFile];  

File offsets are a key aspect of working with files using the NSFileHandle class so it is worth taking extra time to make sure you understand the concept. Without knowing where the current offset is in a file it is impossible to know where in the file data will be read or written.

Reading Data from a File

Once a file has been opened and assigned a file handle, the contents of that file may be read from the current offset position. ThereadDataOfLength method reads a specified number of bytes of data from the file starting at the current offset. For example, the following code reads 5 bytes of data from offset 10 in a file. The data read is returned encapsulated in an NSData object:

[plain]  view plain copy
  1. NSData *databuffer;  
  2.   
  3. file = [NSFileHandle fileHandleForReadingAtPath: @"/tmp/myfile.txt"];  
  4.   
  5. if (file == nil)  
  6.         NSLog(@"Failed to open file");  
  7.   
  8. [file seekToFileOffset: 10];  
  9.   
  10. databuffer = [file readDataOfLength: 5];  
  11.   
  12. [file closeFile];  

Alternatively, the readDataToEndOfFile method will read all the data in the file starting at the current offset and ending at the end of the file.

Writing Data to a File

The writeData method writes the data contained in an NSData object to the file starting at the location of the offset. Note that this does not insert data but rather overwrites any existing data in the file at the corresponding location.

To see this in action we need to begin with a file. Using a text editor, create a file named quickfox.txt, enter the following text and save it in the /tmp directory:

The quick brown fox jumped over the lazy dog

Next, we will write a program that opens the file for updating, seeks to position 10 and then writes some data at that location:

[plain]  view plain copy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. int main (int argc, const char * argv[])  
  4. {  
  5.         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  6.   
  7.         NSFileHandle *file;  
  8.         NSMutableData *data;  
  9.   
  10.         const char *bytestring = "black dog";  
  11.   
  12.         data = [NSMutableData dataWithBytes:bytestring length:strlen(bytestring)];  
  13.   
  14.   
  15.         file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/quickfox.txt"];  
  16.   
  17.         if (file == nil)  
  18.                 NSLog(@"Failed to open file");  
  19.   
  20.   
  21.         [file seekToFileOffset: 10];  
  22.   
  23.         [file writeData: data];  
  24.   
  25.         [file closeFile];  
  26.   
  27.         [pool drain];  
  28.   
  29.         return 0;  
  30. }  

When the above program is compiled and executed the contents of the quickfox.txt will have changed to:

The quick black dog jumped over the lazy dog

Truncating a File

A file may be truncated at the specified offset using the truncateFileAtOffset method. To delete the entire contents of a file, specify an offset of 0 when calling this method:

[plain]  view plain copy
  1. NSFileHandle *file;  
  2.   
  3. file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/quickfox.txt"];  
  4.   
  5. if (file == nil)  
  6.         NSLog(@"Failed to open file");  
  7.   
  8. [file truncateFileAtOffset: 0];  
  9.   
  10. [file closeFile];  
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值