在C中逐块逐行读取文件

时间:2016-04-24 15:16:09

标签: c

我需要从文件中读取4000行,对它们进行一些操作,然后读取下面的4000行,对它们进行一些操作,然后读取下面的4000行,依此类推,直到某些BIG文件结束。如何正确地做到这一点?

这是我的基本代码,它只是从文件中读取所有行而不是逐块读取:

import 'dart:html' as html;
import 'dart:isolate';
import 'dart:math';

SendPort worker;
bool working = false;

main() async{

  await startWorker();

  html.querySelector('#stage').onMouseUp.listen((e){
    if(working)worker.send('stop');
    else worker.send('go');
  });

}

startWorker() async{
  var response = new ReceivePort();

  await Isolate.spawnUri(Uri.parse("worker.dart"), null ,response.sendPort)
      .then((_) => response.listen((msg){

    if(msg is SendPort) {
      worker = msg;
    }
    else {
      messageReceived(msg);
    }
  }));
}

messageReceived(String message){
  switch (message){
    case 'working': working = true;
    break;

    case 'idle': working = false;
      break;

    default : print(message);
      break;
  }
}

2 个答案:

答案 0 :(得分:2)

有什么问题?

您需要使用2个循环。外面的一个会重复阅读大量的行直到EOF。

代码可能如下图所示:

...
while (1) 
{
    /* read <= 4000 lines and process */
}

内心会读取线条并将它们存储起来:

size_t lines = 0; /** next index to be used with lineBuffer  
                  (and number of lines already stored)*/
char *lineBuffer[4000];
char buf[bufSize];

while (lines < 4000 && fgets(buf, sizeof(buf), fp) != NULL)
{
    buf[strlen(buf) - 1] = '\0';
    lineBuffer[lines] = malloc(strlen(buf);
    strcpy(lineBuffer[lines], buf);
    lines++;
}

if (lines == 0) 
{
    break; /* we are done*/
}
/* do processing on data */

/* deallocate dynamic memory */
for (int i = lines - 1; lines>=0; i--) 
{
   free(lineBuffer[i]);
}

lines = 0;

当然你可以使用

来使用静态内存分配
char lineBuffer[4000][bufSize];

而不是mallocing。这将节省使用calloc(400*bufSize);执行alloc / dealloc序列,或在顶层(在循环外)进行分配 但考虑到当前设置总共使用了大约4MB的内存,这留给了个人喜好。

关于表现:
静态分配内存可能会带来一些速度上的好处 您还可以尝试增加stdio使用的缓冲区大小(通过setbuffer()变体从文件中读取更大的块。

这是否会产生任何显着影响取决于您应该采取的一些性能测量(如果首先出现问题)

答案 1 :(得分:1)

好的,然后在堆上分配一个二维数组,并声明类型为size_t的变量n,以跟踪行数。请尝试以下内容:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define bufSize 1024

int main(int argc, char *argv[])
{
    FILE* fp;
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <soure-file>\n", argv[0]);
        return 1;
    }
    if ((fp = fopen(argv[1], "r")) == NULL)
    { /* Open source file. */
        perror("fopen source-file");
        return 1;
    }

    size_t n = 0;
    char(*buf)[bufSize] = malloc(bufSize * 4000);
    if (!buf) {
        fprintf(stderr, "Error - Failed to allocate memory.\n");
        fclose(fp);
        return 1;
    }
    while (1)
    {
        if (fgets(buf[n], bufSize, fp) != NULL) {
            n++;
            if (n == 4000) {
                /* do something */
                // ...
                n = 0;
            }
        }
        else {
            // do something with leftover
            break;
        }
    }
    free(buf);
    fclose(fp);
    return 0;
}