我将通过我制作的应用程序在iphone上存储.xml文件。我写了一些代码:
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *resPath = [documentsPath stringByAppendingPathComponent:@"FILENAME"];
[MY_NSDATAREFERENCE writeToFile:resPath atomically:YES];
这适用于模拟器,但这是保存文件的正确方法吗?
我知道您无法写入应用程序包,但是哪些路径/位置对于写入和读取信息是有效的。
任何有用的帮助!
答案 0 :(得分:3)
是的,假设您从MYDATAREFERENCE
或您选择的其他编码创建了[myString dataUsingEncoding:NSUTF8StringEncoding]
,这将是合适的方法。
在旁注中,我创建了一种简单的文件写入方式(类似于.NET的StreamWriter):
RJRStreamWriter.h
//
// RJRStreamWriter.h
//
// Created by RJ Ross on 10/14/10.
// Copyright 2010 Ultimate Computer Services Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface RJRStreamWriter : NSObject {
NSStringEncoding encoding;
int streamType;
NSOutputStream *m_stream;
NSMutableData *m_data;
NSFileHandle *m_handle;
NSURL *m_url;
NSString *newLine;
}
@property(readwrite, assign) NSStringEncoding encoding;
@property(readwrite, copy) NSString *newLine;
-(id) initWithOutputStream:(NSOutputStream *) stream;
-(id) initWithMutableData:(NSMutableData *) data;
-(id) initWithFileHandle:(NSFileHandle *) handle;
-(id) initWithLocalFile:(NSString *) file andAppend:(BOOL) append;
-(id) initWithURL:(NSURL *) url;
-(void) write:(NSString *) string;
-(void) writeLine:(NSString *) string;
-(void) writeData:(NSData *) data;
@end
RJRStreamWriter.m
//
// RJRStreamWriter.m
//
//
// Created by RJ Ross on 10/14/10.
// Copyright 2010 Ultimate Computer Services Inc. All rights reserved.
//
#import "RJRStreamWriter.h"
#import "Constants.h"
#import "Macros.h"
#import "Exceptions.h"
typedef enum
{
OutputStreamType_OutputStream,
OutputStreamType_MutableData,
OutputStreamType_FileHandle,
OutputStreamType_LocalFile,
OutputStreamType_URL,
} OutputStreamType;
@implementation RJRStreamWriter
@synthesize encoding, newLine;
-(id) initWithOutputStream:(NSOutputStream *)stream
{
if (self = [super init])
{
if (!stream)
@throw [NullArgumentException exceptionWithDescription:@"Stream cannot be null!"];
m_stream = [stream retain];
streamType = OutputStreamType_OutputStream;
encoding = NSUTF8StringEncoding;
newLine = [NEWLINE copy];
}
return self;
}
-(id) initWithMutableData:(NSMutableData *)data
{
if (self = [super init])
{
if (!data)
@throw [NullArgumentException exceptionWithDescription:@"Data cannot be null!"];
m_data = [data retain];
streamType = OutputStreamType_MutableData;
encoding = NSUTF8StringEncoding;
newLine = [NEWLINE copy];
}
return self;
}
-(id) initWithFileHandle:(NSFileHandle *)handle
{
if (self = [super init])
{
if (!handle)
@throw [NullArgumentException exceptionWithDescription:@"Handle cannot be null!"];
m_handle = [handle retain];
streamType = OutputStreamType_FileHandle;
encoding = NSUTF8StringEncoding;
newLine = [NEWLINE copy];
}
return self;
}
-(id) initWithLocalFile:(NSString *)file andAppend:(BOOL)append
{
NSOutputStream *output = [NSOutputStream outputStreamToFileAtPath:file append:append];
self = [self initWithOutputStream:output];
if (!self)
return nil;
streamType = OutputStreamType_LocalFile;
[output open];
return self;
}
-(id) initWithURL:(NSURL *)url
{
NOT_IMPLEMENTED_EXCEPTION;
return nil;
}
-(void) write:(NSString *)string
{
[self writeData:[string dataUsingEncoding:encoding]];
}
-(void) writeLine:(NSString *)string
{
[self writeData:[[NSString stringWithFormat:@"%@%@", string, newLine] dataUsingEncoding:encoding]];
}
-(void) writeData:(NSData *)data
{
switch ((OutputStreamType)streamType) {
case OutputStreamType_OutputStream:
case OutputStreamType_LocalFile: {
const uint8_t *buf = [data bytes];
[m_stream write:buf maxLength:[data length]];
break;
}
case OutputStreamType_MutableData:{
const uint8_t *buf = [data bytes];
[m_data appendBytes:buf length:[data length]];
break;
}
case OutputStreamType_FileHandle: {
[m_handle writeData:data];
break;
}
default:
@throw [ArgumentException exceptionWithDescription:[NSString stringWithFormat:@"Unknown output stream type %i", streamType]];
break;
}
}
-(void) dealloc
{
if (streamType == OutputStreamType_LocalFile)
[m_stream close];
[m_handle release];
[m_stream release];
[m_data release];
[newLine release];
[super dealloc];
}
@end
另请注意,这会使用一些自定义异常类(仅替换为[NSException raise:format:]
和宏(NEWLINE
= \n
NOT_IMPLEMENTED_EXCEPTION
= [NSException raise:@"Not implemented exception" format:@"This method is not yet implemented"]
)
XMLWriter.h
//
// XMLWriter.h
//
// Created by RJ Ross on 11/19/10.
// Copyright 2010 Ultimate Computer Services Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "RJRStreamWriter.h"
@interface XMLWriter : NSObject {
RJRStreamWriter *m_out;
int m_bias;
int m_tab;
NSMutableArray *m_tagStack;
}
/// <summary>Create a new XMLWriter.</summary>
/// <remarks>Create a new XMLWriter.</remarks>
/// <param name="output">the print writer to write the XML to</param>
-(id) initWithWriter:(RJRStreamWriter *) output;
/// <summary>Create a new XMLWriter.</summary>
/// <remarks>Create a new XMLWriter.</remarks>
/// <param name="output">the print writer to write the XML to</param>
/// <param name="tabLength">
/// the number of spaces to use for each
/// level of indentation in the XML file
/// </param>
-(id) initWithWriter:(RJRStreamWriter *) output andTabLength:(int) tabLength;
/// <summary>Print <em>unescaped</em> text into the XML file.</summary>
/// <remarks>
/// Print <em>unescaped</em> text into the XML file. To print
/// escaped text, use the
/// <see cref="Content(string)">Content(string)</see>
/// method instead.
/// </remarks>
/// <param name="text">the text to print. This String will not be escaped.</param>
-(void) print:(NSString *) text;
/// <summary>
/// Print <em>unescaped</em> text into the XML file, followed by
/// a newline.
/// </summary>
/// <remarks>
/// Print <em>unescaped</em> text into the XML file, followed by
/// a newline. To print escaped text, use the
/// <see cref="Content(string)">Content(string)</see>
/// method instead.
/// </remarks>
/// <param name="text">the text to print. This String will not be escaped.</param>
-(void) printLn:(NSString *) text;
/// <summary>Print a newline into the XML file.</summary>
/// <remarks>Print a newline into the XML file.</remarks>
-(void) newLine;
/// <summary>Begin the XML document.</summary>
/// <remarks>
/// Begin the XML document. This must be called before any other
/// formatting methods. This method prints an XML header into
/// the top of the output stream.
/// </remarks>
-(void) begin;
/// <summary>Begin the XML document.</summary>
/// <remarks>
/// Begin the XML document. This must be called before any other
/// formatting methods. This method prints an XML header into
/// the top of the output stream, plus additional header text
/// provided by the client
/// </remarks>
/// <param name="header">header text to insert into the document</param>
/// <param name="bias">the spacing bias to use for all subsequent indenting</param>
-(void) begin:(NSString *) header withBias:(int) bias;
/// <summary>Print a comment in the XML document.</summary>
/// <remarks>
/// Print a comment in the XML document. The comment will be printed
/// according to the current spacing and followed by a newline.
/// </remarks>
/// <param name="comment">the comment text</param>
-(void) comment:(NSString *) comment;
/// <summary>Internal method for printing a tag with attributes.</summary>
/// <remarks>Internal method for printing a tag with attributes.</remarks>
/// <param name="tag">the tag name</param>
/// <param name="names">the names of the attributes</param>
/// <param name="values">the values of the attributes</param>
/// <param name="nattr">the number of attributes</param>
/// <param name="close">
/// true to close the tag, false to leave it
/// open and adjust the spacing
/// </param>
-(void) _tag:(NSString *) tag withNames:(NSArray *) names andValues:(NSArray *) values andNumberOfAttributes:(int) nattr andClose:(BOOL) close;
/// <summary>Print a closed tag with attributes.</summary>
/// <remarks>
/// Print a closed tag with attributes. The tag will be followed by a
/// newline.
/// </remarks>
/// <param name="tag">the tag name</param>
/// <param name="names">the names of the attributes</param>
/// <param name="values">the values of the attributes</param>
/// <param name="nattr">the number of attributes</param>
-(void) tag:(NSString *) tag withNames:(NSArray *) names andValues:(NSArray *) values andNumberOfAttributes:(int) nattr;
/// <summary>Print a start tag with attributes.</summary>
/// <remarks>
/// Print a start tag with attributes. The tag will be followed by a
/// newline, and the indentation level will be increased.
/// </remarks>
/// <param name="tag">the tag name</param>
/// <param name="names">the names of the attributes</param>
/// <param name="values">the values of the attributes</param>
/// <param name="nattr">the number of attributes</param>
-(void) start:(NSString *) tag withNames:(NSArray *) names andValues:(NSArray *) values andNumberOfAttributes:(int) nattr;
/// <summary>Internal method for printing a tag with a single attribute.</summary>
/// <remarks>Internal method for printing a tag with a single attribute.</remarks>
/// <param name="tag">the tag name</param>
/// <param name="name">the name of the attribute</param>
/// <param name="value">the value of the attribute</param>
/// <param name="close">
/// true to close the tag, false to leave it
/// open and adjust the spacing
/// </param>
-(void) _tag:(NSString *)tag withName:(NSString *)name andValue:(NSString *)value andClose:(BOOL)close;
/// <summary>Print a closed tag with one attribute.</summary>
/// <remarks>
/// Print a closed tag with one attribute. The tag will be followed by a
/// newline.
/// </remarks>
/// <param name="tag">the tag name</param>
/// <param name="name">the name of the attribute</param>
/// <param name="value">the value of the attribute</param>
-(void) tag:(NSString *) tag withName:(NSString *) name andValue:(NSString *) value;
/// <summary>Print a start tag with one attribute.</summary>
/// <remarks>
/// Print a start tag with one attribute. The tag will be followed by a
/// newline, and the indentation level will be increased.
/// </remarks>
/// <param name="tag">the tag name</param>
/// <param name="name">the name of the attribute</param>
/// <param name="value">the value of the attribute</param>
-(void) start:(NSString *) tag withName:(NSString *) name AndValue:(NSString *) value;
/// <summary>Print a start tag without attributes.</summary>
/// <remarks>
/// Print a start tag without attributes. The tag will be followed by a
/// newline, and the indentation level will be increased.
/// </remarks>
/// <param name="tag">the tag name</param>
-(void) start:(NSString *) tag;
/// <summary>
/// Print a new content tag with a single attribute, consisting of an
/// open tag, content text, and a closing tag, all on one line.
/// </summary>
/// <remarks>
/// Print a new content tag with a single attribute, consisting of an
/// open tag, content text, and a closing tag, all on one line.
/// </remarks>
/// <param name="tag">the tag name</param>
/// <param name="name">the name of the attribute</param>
/// <param name="value">the value of the attribute, this text will be escaped</param>
/// <param name="content">the text content, this text will be escaped</param>
-(void) contentTag:(NSString *) tag withName:(NSString *) name andValue:(NSString *) value andContent:(NSString *) content;
/// <summary>
/// Print a new content tag with no attributes, consisting of an
/// open tag, content text, and a closing tag, all on one line.
/// </summary>
/// <remarks>
/// Print a new content tag with no attributes, consisting of an
/// open tag, content text, and a closing tag, all on one line.
/// </remarks>
/// <param name="tag">the tag name</param>
/// <param name="content">the text content, this text will be escaped</param>
-(void) contentTag:(NSString *) tag withContent:(NSString *) content;
/// <summary>Print content text.</summary>
/// <remarks>Print content text.</remarks>
/// <param name="content">the content text, this text will be escaped</param>
-(void) content:(NSString *) content;
/// <summary>Finish the XML document.</summary>
/// <remarks>Finish the XML document.</remarks>
-(void) finish;
/// <summary>
/// Finish the XML document, printing the given footer text at the
/// end of the document.
/// </summary>
/// <remarks>
/// Finish the XML document, printing the given footer text at the
/// end of the document.
/// </remarks>
/// <param name="footer">the footer text, this will not be escaped</param>
-(void) finishWithFooter:(NSString *) footer;
/// <summary>
/// Print the current spacing (determined by the indentation level)
/// into the document.
/// </summary>
/// <remarks>
/// Print the current spacing (determined by the indentation level)
/// into the document. This method is used by many of the other
/// formatting methods, and so should only need to be called in
/// the case of custom text printing outside the mechanisms
/// provided by this class.
/// </remarks>
-(void) spacing;
-(void) end;
/// <summary>Escape a string such that it is safe to use in an XML document.</summary>
/// <remarks>Escape a string such that it is safe to use in an XML document.</remarks>
/// <param name="str">the string to escape</param>
-(void) escapeString:(NSString *) str;
@end
XMLWriter.m
//
// XMLWriter.m
//
// Created by RJ Ross on 11/19/10.
// Copyright 2010 Ultimate Computer Services Inc. All rights reserved.
//
#import "XMLWriter.h"
static const char LOWER_RANGE = (char)0x20;
static const char UPPER_RANGE = (char)0x7f;
static const char VALID_CHARS[] = { (char)0x9, (char)0xA, (char)0xD };
static const char INVALID[] = { '<', '>', '"', '\'', '&' };
static const NSString *VALID[] = { @"<", @">", @""", @"&apos", @"&" };
@implementation XMLWriter
-(id) initWithWriter:(RJRStreamWriter *)output
{
return [self initWithWriter:output andTabLength:2];
}
-(id) initWithWriter:(RJRStreamWriter *)output andTabLength:(int)tabLength
{
if (self = [super init])
{
m_tagStack = [[NSMutableArray alloc] init];
m_out = [output retain];
m_tab = tabLength;
}
return self;
}
-(void) print:(NSString *)text
{
[m_out write:text];
}
-(void) printLn:(NSString *)text
{
[m_out writeLine:text];
}
-(void) newLine
{
[m_out writeLine:@""];
}
-(void) begin
{
[m_out writeLine:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"];
}
-(void) begin:(NSString *)header withBias:(int)bias
{
[self begin];
[m_out write:header];
m_bias = bias;
}
-(void) comment:(NSString *)comment
{
[self spacing];
[m_out write:@"<!-- "];
[m_out write:comment];
[m_out write:@" -->"];
[self newLine];
}
-(void) _tag:(NSString *)tag withNames:(NSArray *)names andValues:(NSArray *)values andNumberOfAttributes:(int)nattr andClose:(BOOL)close
{
[self spacing];
[m_out write:@"<"];
[m_out write:tag];
for (int i = 0; i < nattr; i++) {
[m_out write:@" "];
[m_out write:[names objectAtIndex:i]];
[m_out write:@"="];
[m_out write:@"\""];
[self escapeString:[values objectAtIndex:i]];
[m_out write:@"\""];
}
if (close)
{
[m_out write:@"/"];
}
[m_out write:@">"];
[self newLine];
if (!close)
{
[m_tagStack addObject:tag];
}
}
-(void) tag:(NSString *)tag withNames:(NSArray *)names andValues:(NSArray *)values andNumberOfAttributes:(int)nattr
{
[self _tag:tag withNames:names andValues:values andNumberOfAttributes:nattr andClose:YES];
}
-(void) start:(NSString *)tag withNames:(NSArray *)names andValues:(NSArray *)values andNumberOfAttributes:(int)nattr
{
[self _tag:tag withNames:names andValues:values andNumberOfAttributes:nattr andClose:NO];
}
-(void) _tag:(NSString *)tag withName:(NSString *)name andValue:(NSString *)value andClose:(BOOL)close
{
[self spacing];
[m_out write:@"<"];
[m_out write:tag];
[m_out write:@" "];
[m_out write:name];
[m_out write:@"="];
[m_out write:@"\""];
[self escapeString:value];
[m_out write:@"\""];
if (close)
{
[m_out write:@"/"];
}
[m_out write:@">"];
[self newLine];
if (!close)
{
[m_tagStack addObject:tag];
}
}
-(void) tag:(NSString *)tag withName:(NSString *)name andValue:(NSString *)value
{
[self _tag:tag withName:name andValue:value andClose:YES];
}
-(void) start:(NSString *)tag withName:(NSString *)name AndValue:(NSString *)value
{
[self _tag:tag withName:name andValue:value andClose:NO];
}
-(void) start:(NSString *)tag
{
[self _tag:tag withNames:nil andValues:nil andNumberOfAttributes:0 andClose:NO];
}
-(void) end
{
NSString *tag = [[m_tagStack lastObject] retain];
[m_tagStack removeLastObject];
[self spacing];
[m_out write:@"<"];
[m_out write:@"/"];
[m_out write:tag];
[m_out write:@">"];
[self newLine];
[tag release];
}
-(void) contentTag:(NSString *)tag withName:(NSString *)name andValue:(NSString *)value andContent:(NSString *)content
{
[self spacing];
[m_out write:@"<"];
[m_out write:tag];
[m_out write:@" "];
[m_out write:name];
[m_out write:@"="];
[m_out write:@"\""];
[self escapeString:value];
[m_out write:@"\""];
[m_out write:@">"];
[self escapeString:content];
[m_out write:@"<"];
[m_out write:@"/"];
[m_out write:tag];
[m_out write:@">"];
[self newLine];
}
-(void) contentTag:(NSString *)tag withContent:(NSString *)content
{
[self spacing];
[m_out write:@"<"];
[m_out write:tag];
[m_out write:@">"];
[self escapeString:content];
[m_out write:@"<"];
[m_out write:@"/"];
[m_out write:tag];
[m_out write:@">"];
[self newLine];
}
-(void) content:(NSString *)content
{
[self escapeString:content];
}
-(void) finish
{
m_bias = 0;
}
-(void) finishWithFooter:(NSString *)footer
{
m_bias = 0;
[m_out write:footer];
}
-(void) spacing
{
int len = m_bias + m_tagStack.count * m_tab;
for (int i = 0; i < len; i++) {
[m_out write:@" "];
}
}
-(void) escapeString:(NSString *)str
{
if (str == nil)
{
[m_out write:@"null"];
return;
}
int len = str.length;
for (int i = 0; i < len; i++) {
char c = [str characterAtIndex:i];
if ((c < LOWER_RANGE && c != VALID_CHARS[0] && c != VALID_CHARS[1] && c != VALID_CHARS[2]) || (c > UPPER_RANGE))
{
// character out of range, escape character with character value
[m_out write:@"&#"];
[m_out write:[NSString stringWithFormat:@"%i", c]];
[m_out write:@";"];
}
else {
BOOL valid = YES;
for (int j = 4; j >= 0; j--) {
if (INVALID[j] == c)
{
valid = NO;
[m_out write:[NSString stringWithFormat:@"%c", VALID[j]]];
break;
}
}
// if character is valid, dont escape
if (valid)
[m_out write:[NSString stringWithFormat:@"%c", c]];
}
}
}
-(void) dealloc
{
[m_out release];
[m_tagStack release];
[super dealloc];
}
@end
XMLWriter代码来自Java Prefuse Library(www.prefuse.org),而我只是因为从java移植它而受到赞誉。
答案 1 :(得分:2)
是的,您可以在设备上读取/写入应用程序的Documents目录,如此处所示。
您还可以读取/写入应用程序的临时目录,其路径是使用NSTemporaryDirectory
函数找到的。