写入文本文件(附加)时,我写入的最后一个值将替换所有以前的值

When writing to text file (appending) the last value I write replaces all previous values

我正在尝试将我的 SQLite3 table 重现为保存到手机文档中的 .csv 文件。

为了做到这一点,我尝试在文件末尾追加一个新行,每次在我的数组中找到一个对象时,这都有效——但它似乎一遍又一遍地重现最后一行对于我的 sql table 中的确切行数。

这是 SQLite Select 查询:

    NSMutableArray *allGPS = [[NSMutableArray alloc] init];
    GPS *gps = [[GPS alloc] init];
// Open the database from the users filessytem
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"GPS.db"];
    if (sqlite3_open([databasePath UTF8String], &databaseHandle) == SQLITE_OK)
    {
        NSString *sqlStatement = [NSString stringWithFormat:@"SELECT * FROM GPSJob;"];
        sqlite3_stmt *statement;
        if(sqlite3_prepare_v2(databaseHandle, [sqlStatement UTF8String], -1, &statement, NULL) == SQLITE_OK) {
            NSLog(@"Statement prepared");
            while(sqlite3_step(statement) == SQLITE_ROW) 
            {
                [gps setJobNo:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)]];
                [gps setSourceMonitor:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]];
                [gps setPositionNo:[NSNumber numberWithInt:sqlite3_column_int(statement,2)]];
                [gps setLatitude:sqlite3_column_double(statement, 3)];
                [gps setLongitude:sqlite3_column_double(statement, 4)];
                NSLog(@"Source Monitor: %@", [gps sourceMonitor]);
                [allGPS addObject:gps];
            }
        }
                    sqlite3_finalize(statement);
    }

这里是写入.csv文件的方法:

 GPS *saveGPS = [[GPS alloc] init];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@.csv", jobNo]];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
    NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
    DataController *dataController = [[DataController alloc] init];
    NSString *csvTitleString =@"Source/Monitor, PositionNumber, Latitude, Longitude \n";
    [myHandle seekToEndOfFile];
    [myHandle writeData:[csvTitleString dataUsingEncoding:NSUTF8StringEncoding]];
    NSString *csvString = [[NSString alloc] init];
    NSArray *allGPS = [[NSArray alloc]initWithArray:[dataController getAll]];
    for(int i=0;i<(allGPS.count);i++){
        saveGPS = [allGPS objectAtIndex:i];
        csvString = [NSString stringWithFormat:@"%@, %d, %f, %f \n", [saveGPS sourceMonitor], [[saveGPS positionNo] intValue], [saveGPS latitude], [saveGPS longitude]];
        [myHandle seekToEndOfFile];
        [myHandle writeData:[csvString dataUsingEncoding:NSUTF8StringEncoding]];

您在重复循环中始终使用相同的 GPS 实例,因此由于引用语义,对象中的数据将被覆盖,并且在每次迭代中将相同的对象添加到数组中。

移线

GPS *gps = [[GPS alloc] init];

就在行

之前
[gps setJobNo:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)]];

在每次迭代中创建一个新的 GPS 实例

在每次迭代中创建 gps-对象的新实例:

while(sqlite3_step(statement) == SQLITE_ROW) 
{
     gps = [[GPS alloc] init];

     [gps setJobNo:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)]];
     [gps setSourceMonitor:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]];
     [gps setPositionNo:[NSNumber numberWithInt:sqlite3_column_int(statement,2)]];
     [gps setLatitude:sqlite3_column_double(statement, 3)];
     [gps setLongitude:sqlite3_column_double(statement, 4)];
     NSLog(@"Source Monitor: %@", [gps sourceMonitor]);
     [allGPS addObject:gps];
 }