我需要从文件中读取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;
}
}
答案 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;
}