Objective-C: odczyt pliku linia po linii
Jaki jest odpowiedni sposób radzenia sobie z dużymi plikami tekstowymi w Objective-C? Powiedzmy, że muszę czytać każdą linię osobno i chcę traktować każdą linię jako NSString. Jaki jest najskuteczniejszy sposób na to?
Jednym z rozwiązań jest zastosowanie metody NSString:
+ (id)stringWithContentsOfFile:(NSString *)path
encoding:(NSStringEncoding)enc
error:(NSError **)error
A następnie podzielić linie separatorem nowej linii, a następnie iterować nad elementami w tablicy. Wydaje się to jednak dość nieefektywne. Czy nie ma łatwego sposobu traktowania pliku jako strumienia, wyliczania nad każdą linijką, zamiast czytać wszystko na raz? Trochę jak java ' s java. io. Buferedreader.
17 answers
To świetne pytanie. Myślę, że @Diederik ma dobrą odpowiedź, chociaż szkoda, że Cocoa nie ma mechanizmu dokładnie tego, co chcesz zrobić.
NSInputStream
pozwala na odczyt fragmentów N bajtów (bardzo podobnych do java.io.BufferedReader
), ale musisz przekonwertować je na NSString
samodzielnie, a następnie skanować w poszukiwaniu nowych linii (lub innego ogranicznika) i zapisać pozostałe znaki do następnego odczytu lub odczytać więcej znaków, jeśli nowy wiersz nie został jeszcze odczytany. (NSFileHandle
pozwala odczytać NSData
, które można następnie przekonwertować na NSString
, ale zasadniczo jest to ten sam proces.)
Apple ma Stream Programming Guide , który może pomóc w wypełnieniu szczegółów, a to pytanie może również pomóc, jeśli masz do czynienia z buforami uint8_t*
.
Jeśli masz zamiar czytać ciągi takie często (szczególnie w różnych częściach programu), byłoby dobrym pomysłem, aby zamknąć to zachowanie w klasa, która może obsłużyć szczegóły za Ciebie, a nawet subclassing NSInputStream
(jest zaprojektowany do subclassingu ) i dodawanie metod, które pozwalają odczytać dokładnie to, co chcesz.
Dla przypomnienia, myślę, że byłoby miło dodać tę funkcję, i będę złożyć wniosek o ulepszenie czegoś, co sprawia, że jest to możliwe. :-)
Edit: okazuje się, że to żądanie już istnieje. Jest na to Radar z 2006 roku (rdar://4742914 dla Apple-internal osób).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:14
To będzie działać dla ogólnego czytania a String
z Text
.
Jeśli chcesz przeczytać dłuższy tekst (duży rozmiar tekstu) , użyj metody, o której wspominały inne osoby, np. buforowane (zachowaj rozmiar tekstu w pamięci) .
Powiedzmy, że czytasz plik tekstowy.
NSString* filePath = @""//file path...
NSString* fileRoot = [[NSBundle mainBundle]
pathForResource:filePath ofType:@"txt"];
Chcesz pozbyć się nowej linii.
// read everything from text
NSString* fileContents =
[NSString stringWithContentsOfFile:fileRoot
encoding:NSUTF8StringEncoding error:nil];
// first, separate by new line
NSArray* allLinedStrings =
[fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
// then break down even further
NSString* strsInOneLine =
[allLinedStrings objectAtIndex:0];
// choose whatever input identity you have decided. in this case ;
NSArray* singleStrs =
[currentPointString componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:@";"]];
Proszę bardzo.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-26 16:12:02
To powinno załatwić sprawę:
#include <stdio.h>
NSString *readLineAsNSString(FILE *file)
{
char buffer[4096];
// tune this capacity to your liking -- larger buffer sizes will be faster, but
// use more memory
NSMutableString *result = [NSMutableString stringWithCapacity:256];
// Read up to 4095 non-newline characters, then read and discard the newline
int charsRead;
do
{
if(fscanf(file, "%4095[^\n]%n%*c", buffer, &charsRead) == 1)
[result appendFormat:@"%s", buffer];
else
break;
} while(charsRead == 4095);
return result;
}
Stosować w następujący sposób:
FILE *file = fopen("myfile", "r");
// check for NULL
while(!feof(file))
{
NSString *line = readLineAsNSString(file);
// do stuff with line; line is autoreleased, so you should NOT release it (unless you also retain it beforehand)
}
fclose(file);
Ten kod odczytuje Nie-nowe znaki z pliku, do 4095 na raz. Jeśli linia jest dłuższa niż 4095 znaków, czyta się ją tak długo, aż trafi na nową linię lub koniec pliku.
Uwaga: nie testowałem tego kodu. Przetestuj go przed użyciem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-11 20:01:24
Mac OS X to Unix, Objective-C to C superset, więc możesz po prostu użyć old-school fopen
i fgets
z <stdio.h>
. Na pewno zadziała.
[NSString stringWithUTF8String:buf]
konwertuje łańcuch C na NSString
. Istnieją również metody tworzenia łańcuchów w innych kodowaniach i tworzenia bez kopiowania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 23:30:36
Możesz użyć NSInputStream
, który ma podstawową implementację dla strumieni plików. Można odczytywać bajty do bufora (metodaread:maxLength:
). Musisz sam przeskanować bufor w poszukiwaniu nowych linii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-25 16:46:55
Odpowiedni sposób odczytu plików tekstowych w Cocoa / Objective - C jest udokumentowany w podręczniku Apple String programming guide. Sekcja odczytywanie i zapisywanie plików powinna być właśnie tym, czego szukasz. PS: Co to jest "linia"? Dwie części łańcucha oddzielone "\n"? Albo "\r"? Albo "\R\n"? A może chodzi Ci o paragrafy? Wcześniej wspomniany przewodnik zawiera również sekcję dotyczącą dzielenia ciągu znaków na linie lub akapity. (Ta sekcja nazywa się "akapity i podziały wierszy" i jest linked to in the left-hand-side menu of the page I indicated to above. Niestety ta strona nie pozwala mi publikować więcej niż jeden adres URL, ponieważ nie jestem jeszcze godnym zaufania użytkownikiem.)
Parafrazując Knutha: przedwczesna optymalizacja jest źródłem wszelkiego zła. Nie zakładaj, że "wczytanie całego pliku do pamięci" jest powolne. Sprawdziłeś to? Czy wiesz, że to w rzeczywistości wczytuje cały plik do pamięci? Może po prostu zwraca obiekt proxy i czyta za kulisami jako zużywasz sznurek? (Zastrzeżenie: nie mam pojęcia, czy NSString rzeczywiście to robi. Możliwe, że tak.) chodzi o to: najpierw idź z udokumentowanym sposobem robienia rzeczy. Następnie, jeśli benchmarki pokazują, że nie ma to pożądanej wydajności, zoptymalizuj.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-26 23:04:35
Wiele z tych Odpowiedzi to długie fragmenty kodu lub czytane w całym pliku. Lubię używać metod c do tego zadania.
FILE* file = fopen("path to my file", "r");
size_t length;
char *cLine = fgetln(file,&length);
while (length>0) {
char str[length+1];
strncpy(str, cLine, length);
str[length] = '\0';
NSString *line = [NSString stringWithFormat:@"%s",str];
% Do what you want here.
cLine = fgetln(file,&length);
}
Zauważ, że fgetln nie zachowa znaku nowej linii. Ponadto, mamy +1 Długość str, ponieważ chcemy zrobić miejsce dla zakończenia NULL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-07 19:50:09
Aby odczytać plik linia po linii (również dla ekstremalnie dużych plików) można to zrobić za pomocą następujących funkcji:
DDFileReader * reader = [[DDFileReader alloc] initWithFilePath:pathToMyFile];
NSString * line = nil;
while ((line = [reader readLine])) {
NSLog(@"read line: %@", line);
}
[reader release];
Lub:
DDFileReader * reader = [[DDFileReader alloc] initWithFilePath:pathToMyFile];
[reader enumerateLinesUsingBlock:^(NSString * line, BOOL * stop) {
NSLog(@"read line: %@", line);
}];
[reader release];
Klasa DDFileReader, która umożliwia to jest następująca:
Plik Interfejsu (.h):
@interface DDFileReader : NSObject {
NSString * filePath;
NSFileHandle * fileHandle;
unsigned long long currentOffset;
unsigned long long totalFileLength;
NSString * lineDelimiter;
NSUInteger chunkSize;
}
@property (nonatomic, copy) NSString * lineDelimiter;
@property (nonatomic) NSUInteger chunkSize;
- (id) initWithFilePath:(NSString *)aPath;
- (NSString *) readLine;
- (NSString *) readTrimmedLine;
#if NS_BLOCKS_AVAILABLE
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL *))block;
#endif
@end
Realizacja (.m)
#import "DDFileReader.h"
@interface NSData (DDAdditions)
- (NSRange) rangeOfData_dd:(NSData *)dataToFind;
@end
@implementation NSData (DDAdditions)
- (NSRange) rangeOfData_dd:(NSData *)dataToFind {
const void * bytes = [self bytes];
NSUInteger length = [self length];
const void * searchBytes = [dataToFind bytes];
NSUInteger searchLength = [dataToFind length];
NSUInteger searchIndex = 0;
NSRange foundRange = {NSNotFound, searchLength};
for (NSUInteger index = 0; index < length; index++) {
if (((char *)bytes)[index] == ((char *)searchBytes)[searchIndex]) {
//the current character matches
if (foundRange.location == NSNotFound) {
foundRange.location = index;
}
searchIndex++;
if (searchIndex >= searchLength) { return foundRange; }
} else {
searchIndex = 0;
foundRange.location = NSNotFound;
}
}
return foundRange;
}
@end
@implementation DDFileReader
@synthesize lineDelimiter, chunkSize;
- (id) initWithFilePath:(NSString *)aPath {
if (self = [super init]) {
fileHandle = [NSFileHandle fileHandleForReadingAtPath:aPath];
if (fileHandle == nil) {
[self release]; return nil;
}
lineDelimiter = [[NSString alloc] initWithString:@"\n"];
[fileHandle retain];
filePath = [aPath retain];
currentOffset = 0ULL;
chunkSize = 10;
[fileHandle seekToEndOfFile];
totalFileLength = [fileHandle offsetInFile];
//we don't need to seek back, since readLine will do that.
}
return self;
}
- (void) dealloc {
[fileHandle closeFile];
[fileHandle release], fileHandle = nil;
[filePath release], filePath = nil;
[lineDelimiter release], lineDelimiter = nil;
currentOffset = 0ULL;
[super dealloc];
}
- (NSString *) readLine {
if (currentOffset >= totalFileLength) { return nil; }
NSData * newLineData = [lineDelimiter dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle seekToFileOffset:currentOffset];
NSMutableData * currentData = [[NSMutableData alloc] init];
BOOL shouldReadMore = YES;
NSAutoreleasePool * readPool = [[NSAutoreleasePool alloc] init];
while (shouldReadMore) {
if (currentOffset >= totalFileLength) { break; }
NSData * chunk = [fileHandle readDataOfLength:chunkSize];
NSRange newLineRange = [chunk rangeOfData_dd:newLineData];
if (newLineRange.location != NSNotFound) {
//include the length so we can include the delimiter in the string
chunk = [chunk subdataWithRange:NSMakeRange(0, newLineRange.location+[newLineData length])];
shouldReadMore = NO;
}
[currentData appendData:chunk];
currentOffset += [chunk length];
}
[readPool release];
NSString * line = [[NSString alloc] initWithData:currentData encoding:NSUTF8StringEncoding];
[currentData release];
return [line autorelease];
}
- (NSString *) readTrimmedLine {
return [[self readLine] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
#if NS_BLOCKS_AVAILABLE
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block {
NSString * line = nil;
BOOL stop = NO;
while (stop == NO && (line = [self readLine])) {
block(line, &stop);
}
}
#endif
@end
Zajęcia wykonał Dave DeLong
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:15
Tak jak powiedział @ porneL, C api jest bardzo przydatne.
NSString* fileRoot = [[NSBundle mainBundle] pathForResource:@"record" ofType:@"txt"];
FILE *file = fopen([fileRoot UTF8String], "r");
char buffer[256];
while (fgets(buffer, 256, file) != NULL){
NSString* result = [NSString stringWithUTF8String:buffer];
NSLog(@"%@",result);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-28 03:47:46
Jak inni odpowiedzieli, zarówno NSInputStream, jak i NSFileHandle są dobrymi opcjami, ale można to również zrobić w dość kompaktowy sposób z nsdata i mapowaniem pamięci:
BRLineReader.h#import <Foundation/Foundation.h>
@interface BRLineReader : NSObject
@property (readonly, nonatomic) NSData *data;
@property (readonly, nonatomic) NSUInteger linesRead;
@property (strong, nonatomic) NSCharacterSet *lineTrimCharacters;
@property (readonly, nonatomic) NSStringEncoding stringEncoding;
- (instancetype)initWithFile:(NSString *)filePath encoding:(NSStringEncoding)encoding;
- (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
- (NSString *)readLine;
- (NSString *)readTrimmedLine;
- (void)setLineSearchPosition:(NSUInteger)position;
@end
BRLineReader.m
#import "BRLineReader.h"
static unsigned char const BRLineReaderDelimiter = '\n';
@implementation BRLineReader
{
NSRange _lastRange;
}
- (instancetype)initWithFile:(NSString *)filePath encoding:(NSStringEncoding)encoding
{
self = [super init];
if (self) {
NSError *error = nil;
_data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedAlways error:&error];
if (!_data) {
NSLog(@"%@", [error localizedDescription]);
}
_stringEncoding = encoding;
_lineTrimCharacters = [NSCharacterSet whitespaceAndNewlineCharacterSet];
}
return self;
}
- (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding
{
self = [super init];
if (self) {
_data = data;
_stringEncoding = encoding;
_lineTrimCharacters = [NSCharacterSet whitespaceAndNewlineCharacterSet];
}
return self;
}
- (NSString *)readLine
{
NSUInteger dataLength = [_data length];
NSUInteger beginPos = _lastRange.location + _lastRange.length;
NSUInteger endPos = 0;
if (beginPos == dataLength) {
// End of file
return nil;
}
unsigned char *buffer = (unsigned char *)[_data bytes];
for (NSUInteger i = beginPos; i < dataLength; i++) {
endPos = i;
if (buffer[i] == BRLineReaderDelimiter) break;
}
// End of line found
_lastRange = NSMakeRange(beginPos, endPos - beginPos + 1);
NSData *lineData = [_data subdataWithRange:_lastRange];
NSString *line = [[NSString alloc] initWithData:lineData encoding:_stringEncoding];
_linesRead++;
return line;
}
- (NSString *)readTrimmedLine
{
return [[self readLine] stringByTrimmingCharactersInSet:_lineTrimCharacters];
}
- (void)setLineSearchPosition:(NSUInteger)position
{
_lastRange = NSMakeRange(position, 0);
_linesRead = 0;
}
@end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-21 19:36:41
Ta odpowiedź nie jest ObjC ale C.
Ponieważ ObjC jest oparty na 'C', dlaczego nie używać fgets?
I tak, jestem pewien, że ObjC ma własną metodę - po prostu nie jestem jeszcze wystarczająco biegły, aby wiedzieć, co to jest:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-25 15:19:34
Z odpowiedzi @ Adam Rosenfield, ciąg formatowania fscanf
zostanie zmieniony jak poniżej:
"%4095[^\r\n]%n%*[\n\r]"
Będzie działać w systemach OSX, linux, Windows.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-27 09:16:02
Używanie kategorii lub rozszerzenia, aby ułatwić nam życie.
extension String {
func lines() -> [String] {
var lines = [String]()
self.enumerateLines { (line, stop) -> () in
lines.append(line)
}
return lines
}
}
// then
for line in string.lines() {
// do the right thing
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-07 04:57:33
[[4]}znalazłem odpowiedź @lukaswelte i kod z Dave DeLong bardzo pomocne. Szukałem rozwiązania tego problemu, ale musiałem parsować duże pliki przez \r\n
, a nie tylko \n
.
Napisany kod zawiera błąd, jeśli parsowanie przez więcej niż jeden znak. Zmieniłem Kod jak poniżej.
.plik h:
#import <Foundation/Foundation.h>
@interface FileChunkReader : NSObject {
NSString * filePath;
NSFileHandle * fileHandle;
unsigned long long currentOffset;
unsigned long long totalFileLength;
NSString * lineDelimiter;
NSUInteger chunkSize;
}
@property (nonatomic, copy) NSString * lineDelimiter;
@property (nonatomic) NSUInteger chunkSize;
- (id) initWithFilePath:(NSString *)aPath;
- (NSString *) readLine;
- (NSString *) readTrimmedLine;
#if NS_BLOCKS_AVAILABLE
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL *))block;
#endif
@end
.plik m:
#import "FileChunkReader.h"
@interface NSData (DDAdditions)
- (NSRange) rangeOfData_dd:(NSData *)dataToFind;
@end
@implementation NSData (DDAdditions)
- (NSRange) rangeOfData_dd:(NSData *)dataToFind {
const void * bytes = [self bytes];
NSUInteger length = [self length];
const void * searchBytes = [dataToFind bytes];
NSUInteger searchLength = [dataToFind length];
NSUInteger searchIndex = 0;
NSRange foundRange = {NSNotFound, searchLength};
for (NSUInteger index = 0; index < length; index++) {
if (((char *)bytes)[index] == ((char *)searchBytes)[searchIndex]) {
//the current character matches
if (foundRange.location == NSNotFound) {
foundRange.location = index;
}
searchIndex++;
if (searchIndex >= searchLength)
{
return foundRange;
}
} else {
searchIndex = 0;
foundRange.location = NSNotFound;
}
}
if (foundRange.location != NSNotFound
&& length < foundRange.location + foundRange.length )
{
// if the dataToFind is partially found at the end of [self bytes],
// then the loop above would end, and indicate the dataToFind is found
// when it only partially was.
foundRange.location = NSNotFound;
}
return foundRange;
}
@end
@implementation FileChunkReader
@synthesize lineDelimiter, chunkSize;
- (id) initWithFilePath:(NSString *)aPath {
if (self = [super init]) {
fileHandle = [NSFileHandle fileHandleForReadingAtPath:aPath];
if (fileHandle == nil) {
return nil;
}
lineDelimiter = @"\n";
currentOffset = 0ULL; // ???
chunkSize = 128;
[fileHandle seekToEndOfFile];
totalFileLength = [fileHandle offsetInFile];
//we don't need to seek back, since readLine will do that.
}
return self;
}
- (void) dealloc {
[fileHandle closeFile];
currentOffset = 0ULL;
}
- (NSString *) readLine {
if (currentOffset >= totalFileLength)
{
return nil;
}
@autoreleasepool {
NSData * newLineData = [lineDelimiter dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle seekToFileOffset:currentOffset];
unsigned long long originalOffset = currentOffset;
NSMutableData *currentData = [[NSMutableData alloc] init];
NSData *currentLine = [[NSData alloc] init];
BOOL shouldReadMore = YES;
while (shouldReadMore) {
if (currentOffset >= totalFileLength)
{
break;
}
NSData * chunk = [fileHandle readDataOfLength:chunkSize];
[currentData appendData:chunk];
NSRange newLineRange = [currentData rangeOfData_dd:newLineData];
if (newLineRange.location != NSNotFound) {
currentOffset = originalOffset + newLineRange.location + newLineData.length;
currentLine = [currentData subdataWithRange:NSMakeRange(0, newLineRange.location)];
shouldReadMore = NO;
}else{
currentOffset += [chunk length];
}
}
if (currentLine.length == 0 && currentData.length > 0)
{
currentLine = currentData;
}
return [[NSString alloc] initWithData:currentLine encoding:NSUTF8StringEncoding];
}
}
- (NSString *) readTrimmedLine {
return [[self readLine] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
#if NS_BLOCKS_AVAILABLE
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block {
NSString * line = nil;
BOOL stop = NO;
while (stop == NO && (line = [self readLine])) {
block(line, &stop);
}
}
#endif
@end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:22
Dodaję to, ponieważ wszystkie inne odpowiedzi, które próbowałem, wypadły tak czy inaczej. Poniższa metoda może obsługiwać duże pliki, dowolne długie linie, a także puste linie. Został przetestowany z rzeczywistą zawartością i usunie znak nowej linii z wyjścia.
- (NSString*)readLineFromFile:(FILE *)file
{
char buffer[4096];
NSMutableString *result = [NSMutableString stringWithCapacity:1000];
int charsRead;
do {
if(fscanf(file, "%4095[^\r\n]%n%*[\n\r]", buffer, &charsRead) == 1) {
[result appendFormat:@"%s", buffer];
}
else {
break;
}
} while(charsRead == 4095);
return result.length ? result : nil;
}
Kredyt idzie do @ Adam Rosenfield i @sooop
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 09:47:38
Oto proste rozwiązanie, którego używam dla mniejszych plików:
NSString *path = [[NSBundle mainBundle] pathForResource:@"Terrain1" ofType:@"txt"];
NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:nil];
NSArray *lines = [contents componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\r\n"]];
for (NSString* line in lines) {
if (line.length) {
NSLog(@"line: %@", line);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-25 08:21:39
Użyj tego skryptu, działa świetnie:
NSString *path = @"/Users/xxx/Desktop/names.txt";
NSError *error;
NSString *stringFromFileAtPath = [NSString stringWithContentsOfFile: path
encoding: NSUTF8StringEncoding
error: &error];
if (stringFromFileAtPath == nil) {
NSLog(@"Error reading file at %@\n%@", path, [error localizedFailureReason]);
}
NSLog(@"Contents:%@", stringFromFileAtPath);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-17 13:43:55