67.文件映射为内存进行操作与多线程 以及 文件映射到内存根据索引进行内存来实现读取多线程操作

问题引出:

//有限的额内存情况怎么干活
//索引载入内存,多线程
//索引映射为内存



一.载入内存,按行读取进行多线程

  • 定义路径以及其他信息

    1 char path[256] = "kaifangX.txt";
    2 char indexpath[256] = "indexkf.txt";
    3 #define  N 20151574
  • 创建索引
    1 struct index
    2 {
    3     int *pindex;//地址
    4     int length;
    5 }allindex = {0};
  • 读取文件到内存

     1 void readmem()
     2 {
     3     allindex.length = N;
     4     allindex.pindex = calloc(N, sizeof(int));
     5
     6
     7     FILE *pfw = fopen(indexpath, "rb");
     8     fread(allindex.pindex, sizeof(int),N,pfw);
     9     fclose(pfw);
    10 }
  • 创建索引的线程结构体,每一个线程读取length的长度的行数

     1 void readmem()
     2 {
     3     allindex.length = N;
     4     allindex.pindex = calloc(N, sizeof(int));
     5
     6
     7     FILE *pfw = fopen(indexpath, "rb");
     8     fread(allindex.pindex, sizeof(int),N,pfw);
     9     fclose(pfw);
    10 }
  • 多线程函数

     1 void run(void *p)
     2 {
     3     struct info *pi = p;//参数
     4     for (int  i = 0; i < pi->length-1; i++)//限定
     5     {
     6         //起始地址到结束地址之间是一个字符串,可以读取出来
     7         char *start = infoall.pfilestart + pi->pstart[i];//起始地址
     8         char *end = infoall.pfilestart + pi->pstart[i + 1];//结束地址
     9
    10
    11
    12         char *str = calloc(500, 1);//分配内存用于拷贝字符串,文件整块,没有/0,有/n
    13         if (str != NULL)//分配成功
    14         {
    15             strncpy(str, start, pi->pstart[i + 1] - pi->pstart[i ]);//拷贝字符串
    16             if (str != NULL)
    17             {
    18                 char *ps = strstr(str, pi->findstr);//检索
    19                 if (ps != NULL)
    20                 {
    21                     printf("%s", str);
    22                 }
    23             }
    24
    25         }
    26         free(str);//释放
    27     }
    28 }
  • 载入到内存进行多线程检索

     1 //根据内存进行多线程索引
     2 void test1()
     3 {
     4     printf("please input");
     5     char str[100];
     6     scanf("%s", str);
     7 #define nthread 100
     8     struct info pthread[nthread] = {0};
     9     HANDLE hd[nthread] = { 0 };//线程参数,线程句柄
    10     if (N%nthread==0)
    11     {
    12         for (int i = 0; i < nthread; i++)
    13         {
    14             pthread[i].id = i;
    15             pthread[i].length = N / nthread;
    16             pthread[i].pstart = allindex.pindex + i*(N / nthread);
    17             strcpy(pthread[i].findstr,str );
    18             _beginthread(run, 0, &pthread[i]);
    19         }
    20     }
    21     else
    22     {
    23         for (int i = 0; i < nthread-1; i++)
    24         {
    25             pthread[i].id = i;
    26             pthread[i].length = N / (nthread - 1);
    27             pthread[i].pstart = allindex.pindex + i*(N / (nthread - 1));
    28             strcpy(pthread[i].findstr, str);
    29             _beginthread(run, 0, &pthread[i]);
    30         }
    31         int i = nthread - 1;
    32         pthread[i].id = i;
    33         pthread[i].length = N % (nthread - 1);
    34         pthread[i].pstart = allindex.pindex + i*(N / (nthread - 1));
    35         strcpy(pthread[i].findstr, str);
    36         _beginthread(run, 0, &pthread[i]);
    37
    38     }
    39     WaitForMultipleObjects(nthread, hd, TRUE, INFINITE);//等待
    40
    41
    42     system("pause");
    43
    44 }

二.内存映射进行多线程检索

  • 创建文件映射内存的首地址和尾地址

     1 struct
     2 {
     3     //文本文件首尾地址
     4     char *pfilestart;
     5     char *pfileend;
     6     //索引文件首尾地址
     7     char *pindexfilestart;
     8     char *pindexfileend;
     9
    10 }infoall = {0};
  • 映射文本文件到内存,文件是独家享有

     1 void map1()
     2 {
     3     //打开一个文件
     4     HANDLE hfile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
     5         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     6
     7     if (hfile == INVALID_HANDLE_VALUE)
     8     {
     9         printf("打开文件失败");
    10         system("pause");
    11     }
    12     //获取文件大小
    13     printf("\n%d", GetFileSize(hfile, NULL));
    14
    15     HANDLE hmap = CreateFileMappingA(hfile,
    16         NULL, PAGE_READWRITE | SEC_COMMIT,//读写
    17         0,
    18         GetFileSize(hfile, NULL) + 1,//大小
    19         NULL);
    20
    21     if (hmap == NULL)
    22     {
    23         printf("映射失败");
    24         CloseHandle(hfile);
    25         system("pause");
    26     }
    27
    28     //创建一个指针,存储映射以后的首地址
    29     PVOID pvfile = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
    30
    31     if (pvfile == NULL)
    32     {
    33         printf("指针映射失败");
    34         CloseHandle(hfile);
    35         CloseHandle(hmap);
    36         system("pause");
    37
    38     }
    39     puts("映射成功");
    40     char *pstart = pvfile;//首地址
    41     char *pend = pstart + GetFileSize(hfile, NULL);//结束地址
    42     infoall.pfileend = pend;//保存地址
    43     infoall.pfilestart = pstart;
    44 }
  • 映射索引文件

     1 void map2()
     2 {
     3     HANDLE hfile = CreateFileA(indexpath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
     4         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);//打开一个文件
     5
     6     if (hfile == INVALID_HANDLE_VALUE)
     7     {
     8         printf("打开文件失败");
     9         system("pause");
    10     }
    11     printf("\n%d", GetFileSize(hfile, NULL));//获取文件大小
    12     HANDLE hmap = CreateFileMappingA(hfile,
    13         NULL, PAGE_READWRITE | SEC_COMMIT,//读写
    14         0,
    15         GetFileSize(hfile, NULL) + 1,//大小
    16         NULL);
    17     if (hmap == NULL)
    18     {
    19         printf("映射失败");
    20         CloseHandle(hfile);
    21         system("pause");
    22     }
    23     PVOID pvfile = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
    24     //创建一个指针,存储映射以后的首地址
    25     if (pvfile == NULL)
    26     {
    27         printf("指针映射失败");
    28         CloseHandle(hfile);
    29         CloseHandle(hmap);
    30         system("pause");
    31
    32     }
    33     puts("映射成功");
    34     char *pstart = pvfile;//首地址
    35     char *pend = pstart + GetFileSize(hfile, NULL);//结束地址
    36     infoall.pindexfileend = pend;//保存地址
    37     infoall.pindexfilestart = pstart;
    38 }
  • 内存映射多线程结构体

    1 struct minfo
    2 {
    3     int*pstart;
    4     int length;//0   9 10
    5     int id;
    6     char findstr[20];
    7 };
  • 内存映射多线程函数

     1 void mrun(void *p)
     2 {
     3     struct minfo *pi = p;
     4     for (int i = 0; i < pi->length - 1; i++)
     5     {
     6         char *start = infoall.pfilestart + pi->pstart[i];//起始地址
     7         char *end = infoall.pfilestart + pi->pstart[i + 1];//结束地址
     8         char *str = calloc(500, 1);//分配内存用于拷贝字符串
     9         if (str != NULL)//分配成功
    10         {
    11             strncpy(str, start, pi->pstart[i + 1] - pi->pstart[i]);//拷贝字符串
    12             if (str != NULL)
    13             {
    14                 char *ps = strstr(str, pi->findstr);
    15                 if (ps != NULL)
    16                 {
    17                     printf("%s", str);
    18                 }
    19             }
    20
    21         }
    22         free(str);//释放
    23
    24
    25     }
    26 }
  • 创建多线程

     1 void test2()
     2 {
     3     printf("please input");
     4     char str[100];
     5     scanf("%s", str);
     6 #define nthread 100
     7     struct minfo pthread[nthread] = { 0 };
     8     HANDLE hd[nthread] = { 0 };//线程参数,线程句柄
     9     if (N%nthread == 0)
    10     {
    11         for (int i = 0; i < nthread; i++)
    12         {
    13             pthread[i].id = i;
    14             pthread[i].length = N / nthread;
    15             pthread[i].pstart =   ((int*)infoall.pindexfilestart) + i*(N / nthread);
    16             strcpy(pthread[i].findstr, str);
    17             _beginthread(mrun, 0, &pthread[i]);
    18         }
    19
    20
    21     }
    22     else
    23     {
    24         for (int i = 0; i < nthread - 1; i++)
    25         {
    26             pthread[i].id = i;
    27             pthread[i].length = N / (nthread - 1);             //索引对应的位置信息
    28             pthread[i].pstart = ((int*)infoall.pindexfilestart) + i*(N / (nthread - 1));
    29             strcpy(pthread[i].findstr, str);
    30             _beginthread(mrun, 0, &pthread[i]);
    31         }
    32         int i = nthread - 1;
    33         pthread[i].id = i;
    34         pthread[i].length = N % (nthread - 1);
    35         pthread[i].pstart = ((int*)infoall.pindexfilestart) + i*(N / (nthread - 1));
    36         strcpy(pthread[i].findstr, str);
    37         _beginthread(mrun, 0, &pthread[i]);
    38
    39     }
    40     WaitForMultipleObjects(nthread, hd, TRUE, INFINITE);
    41
    42
    43     system("pause");
    44
    45 }

完整代码:

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<Windows.h>
  5 #include<process.h>
  6 //有限的额内存情况怎么干活
  7 //索引载入内存,多线程
  8 //索引映射为内存
  9
 10
 11 char path[256] = "kaifangX.txt";
 12 char indexpath[256] = "indexkf.txt";
 13 #define  N 20151574
 14
 15 //创建文件映射内存的首地址和尾地址
 16 struct
 17 {
 18     //文本文件首尾地址
 19     char *pfilestart;
 20     char *pfileend;
 21     //索引文件首尾地址
 22     char *pindexfilestart;
 23     char *pindexfileend;
 24
 25 }infoall = {0};
 26
 27
 28 //映射文本文件到内存,文件是独家享有
 29 void map1()
 30 {
 31     //打开一个文件
 32     HANDLE hfile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
 33         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 34
 35     if (hfile == INVALID_HANDLE_VALUE)
 36     {
 37         printf("打开文件失败");
 38         system("pause");
 39     }
 40     //获取文件大小
 41     printf("\n%d", GetFileSize(hfile, NULL));
 42
 43     HANDLE hmap = CreateFileMappingA(hfile,
 44         NULL, PAGE_READWRITE | SEC_COMMIT,//读写
 45         0,
 46         GetFileSize(hfile, NULL) + 1,//大小
 47         NULL);
 48
 49     if (hmap == NULL)
 50     {
 51         printf("映射失败");
 52         CloseHandle(hfile);
 53         system("pause");
 54     }
 55
 56     //创建一个指针,存储映射以后的首地址
 57     PVOID pvfile = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
 58
 59     if (pvfile == NULL)
 60     {
 61         printf("指针映射失败");
 62         CloseHandle(hfile);
 63         CloseHandle(hmap);
 64         system("pause");
 65
 66     }
 67     puts("映射成功");
 68     char *pstart = pvfile;//首地址
 69     char *pend = pstart + GetFileSize(hfile, NULL);//结束地址
 70     infoall.pfileend = pend;//保存地址
 71     infoall.pfilestart = pstart;
 72 }
 73
 74 //映射索引文件到内存
 75 void map2()
 76 {
 77     HANDLE hfile = CreateFileA(indexpath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
 78         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);//打开一个文件
 79
 80     if (hfile == INVALID_HANDLE_VALUE)
 81     {
 82         printf("打开文件失败");
 83         system("pause");
 84     }
 85     printf("\n%d", GetFileSize(hfile, NULL));//获取文件大小
 86     HANDLE hmap = CreateFileMappingA(hfile,
 87         NULL, PAGE_READWRITE | SEC_COMMIT,//读写
 88         0,
 89         GetFileSize(hfile, NULL) + 1,//大小
 90         NULL);
 91     if (hmap == NULL)
 92     {
 93         printf("映射失败");
 94         CloseHandle(hfile);
 95         system("pause");
 96     }
 97     PVOID pvfile = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
 98     //创建一个指针,存储映射以后的首地址
 99     if (pvfile == NULL)
100     {
101         printf("指针映射失败");
102         CloseHandle(hfile);
103         CloseHandle(hmap);
104         system("pause");
105
106     }
107     puts("映射成功");
108     char *pstart = pvfile;//首地址
109     char *pend = pstart + GetFileSize(hfile, NULL);//结束地址
110     infoall.pindexfileend = pend;//保存地址
111     infoall.pindexfilestart = pstart;
112 }
113
114 //读取索引到内存
115 struct index
116 {
117     int *pindex;//地址
118     int length;
119 }allindex = {0};
120
121 //读取文件到内存
122 void readmem()
123 {
124     allindex.length = N;
125     allindex.pindex = calloc(N, sizeof(int));
126
127
128     FILE *pfw = fopen(indexpath, "rb");
129     fread(allindex.pindex, sizeof(int),N,pfw);
130     fclose(pfw);
131 }
132
133 //创建索引的线程结构体,每一个线程读取length的长度的行数
134 struct info
135 {
136     int*pstart;//索引的收地址
137     int length;//长度
138     int id;//编号
139     char findstr[20];//查找的字符串
140 };
141
142 //多线程函数
143 void run(void *p)
144 {
145     struct info *pi = p;//参数
146     for (int  i = 0; i < pi->length-1; i++)//限定
147     {
148         //起始地址到结束地址之间是一个字符串,可以读取出来
149         char *start = infoall.pfilestart + pi->pstart[i];//起始地址
150         char *end = infoall.pfilestart + pi->pstart[i + 1];//结束地址
151
152
153
154         char *str = calloc(500, 1);//分配内存用于拷贝字符串,文件整块,没有/0,有/n
155         if (str != NULL)//分配成功
156         {
157             strncpy(str, start, pi->pstart[i + 1] - pi->pstart[i ]);//拷贝字符串
158             if (str != NULL)
159             {
160                 char *ps = strstr(str, pi->findstr);//检索
161                 if (ps != NULL)
162                 {
163                     printf("%s", str);
164                 }
165             }
166
167         }
168         free(str);//释放
169     }
170 }
171
172 //根据内存进行多线程索引
173 void test1()
174 {
175     printf("please input");
176     char str[100];
177     scanf("%s", str);
178 #define nthread 100
179     struct info pthread[nthread] = {0};
180     HANDLE hd[nthread] = { 0 };//线程参数,线程句柄
181     if (N%nthread==0)
182     {
183         for (int i = 0; i < nthread; i++)
184         {
185             pthread[i].id = i;
186             pthread[i].length = N / nthread;
187             pthread[i].pstart = allindex.pindex + i*(N / nthread);
188             strcpy(pthread[i].findstr,str );
189             _beginthread(run, 0, &pthread[i]);
190         }
191     }
192     else
193     {
194         for (int i = 0; i < nthread-1; i++)
195         {
196             pthread[i].id = i;
197             pthread[i].length = N / (nthread - 1);
198             pthread[i].pstart = allindex.pindex + i*(N / (nthread - 1));
199             strcpy(pthread[i].findstr, str);
200             _beginthread(run, 0, &pthread[i]);
201         }
202         int i = nthread - 1;
203         pthread[i].id = i;
204         pthread[i].length = N % (nthread - 1);
205         pthread[i].pstart = allindex.pindex + i*(N / (nthread - 1));
206         strcpy(pthread[i].findstr, str);
207         _beginthread(run, 0, &pthread[i]);
208
209     }
210     WaitForMultipleObjects(nthread, hd, TRUE, INFINITE);//等待
211
212
213     system("pause");
214
215 }
216
217
218 //内存映射结构体
219 struct minfo
220 {
221     int*pstart;
222     int length;//0   9 10
223     int id;
224     char findstr[20];
225 };
226
227 void mrun(void *p)
228 {
229     struct minfo *pi = p;
230     for (int i = 0; i < pi->length - 1; i++)
231     {
232         char *start = infoall.pfilestart + pi->pstart[i];//起始地址
233         char *end = infoall.pfilestart + pi->pstart[i + 1];//结束地址
234         char *str = calloc(500, 1);//分配内存用于拷贝字符串
235         if (str != NULL)//分配成功
236         {
237             strncpy(str, start, pi->pstart[i + 1] - pi->pstart[i]);//拷贝字符串
238             if (str != NULL)
239             {
240                 char *ps = strstr(str, pi->findstr);
241                 if (ps != NULL)
242                 {
243                     printf("%s", str);
244                 }
245             }
246
247         }
248         free(str);//释放
249
250
251     }
252 }
253
254 //根据内存映射进行多线程索引
255 void test2()
256 {
257     printf("please input");
258     char str[100];
259     scanf("%s", str);
260 #define nthread 100
261     struct minfo pthread[nthread] = { 0 };
262     HANDLE hd[nthread] = { 0 };//线程参数,线程句柄
263     if (N%nthread == 0)
264     {
265         for (int i = 0; i < nthread; i++)
266         {
267             pthread[i].id = i;
268             pthread[i].length = N / nthread;
269             pthread[i].pstart =   ((int*)infoall.pindexfilestart) + i*(N / nthread);
270             strcpy(pthread[i].findstr, str);
271             _beginthread(mrun, 0, &pthread[i]);
272         }
273
274
275     }
276     else
277     {
278         for (int i = 0; i < nthread - 1; i++)
279         {
280             pthread[i].id = i;
281             pthread[i].length = N / (nthread - 1);
282             pthread[i].pstart = ((int*)infoall.pindexfilestart) + i*(N / (nthread - 1));
283             strcpy(pthread[i].findstr, str);
284             _beginthread(mrun, 0, &pthread[i]);
285         }
286         int i = nthread - 1;
287         pthread[i].id = i;
288         pthread[i].length = N % (nthread - 1);
289         pthread[i].pstart = ((int*)infoall.pindexfilestart) + i*(N / (nthread - 1));
290         strcpy(pthread[i].findstr, str);
291         _beginthread(mrun, 0, &pthread[i]);
292
293     }
294     WaitForMultipleObjects(nthread, hd, TRUE, INFINITE);
295
296
297     system("pause");
298
299 }
300
301 void main()
302 {
303     //readmem();
304     map1();//一旦被映射,文件被锁定
305     map2();
306     //test1();
307     test2();
308     getchar();
309 }

原文地址:https://www.cnblogs.com/xiaochi/p/8443477.html

时间: 2024-09-30 06:12:39

67.文件映射为内存进行操作与多线程 以及 文件映射到内存根据索引进行内存来实现读取多线程操作的相关文章

maven-jetty-plugin保存文件报错:请求的操作无法在使用用户映射区域打开的文件上执行

使用jetty-maven-plugin 在eclipse中进行运行调试,碰到无法编辑保存webapp下的文件 提示:请求的操作无法在使用用户映射区域打开的文件上执行 解决方法: 从 jetty 7 开始,jar存放在maven仓库中的路径为org/eclise/jetty/jetty-webapp 打开对应的版本的jar包修改jar中的org/mortbay/jetty/webapp/webdefault.xml文件 Java代码 <init-param> <param-name>

海量数据面试题整理1.给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是

海量数据面试题整理 1. 给定a.b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a.b文件共同的url? 方案1:可以估计每个文件安的大小为50G×64=320G,远远大于内存限制的4G.所以不可能将其完全加载到内存中处理.考虑采取分而治之的方法. s 遍历文件a,对每个url求取,然后根据所取得的值将url分别存储到1000个小文件(记为)中.这样每个小文件的大约为300M. s 遍历文件b,采取和a相同的方式将url分别存储到1000各小文件(记为).这样

file_operation(文件操作)file(文件)inode(节点)

转自:qian-xu-feng file_operation就是把系统调用和驱动程序关联起来的关键数据结构.这个结构的每一个成员都对应着一个系统调用.读取file_operation中相应的函数指针,接着把控制权转交给函数,从而完成了Linux设备驱动程序的工作. 在系统内部,I/O设备的存取操作通过特定的入口点来进行,而这组特定的入口点恰恰是由设备驱动程序提供的.通常这组设备驱动程序接口是由结构file_operations结构体向系统说明的,它定义在include/linux/fs.h中.

测试利用多线程进行文件的写操作

最近学习NIO技术,了解了有关channel通道.buffer缓存以及selector选择器等技术,萌发了想写一个多点下载的一个简单测试demo.我将这个demo分成两步,第一步先实现将一个文件分段复制到一个文件中(通常我们是将文件以流的形式一个字节一个字节的复制到目标文件中,现在我们是将文件分段,启用多个线程,每个线程复制一部分,然后再根据原文件分段的位置组装成一个文件,实现高效的目的).下面帖源码 /** * 测试利用多线程进行文件的写操作 * @author gcl * @version

java使用Jsch实现远程操作linux服务器进行文件上传、下载,删除和显示目录信息

1.java使用Jsch实现远程操作linux服务器进行文件上传.下载,删除和显示目录信息. 参考链接:https://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html https://www.cnblogs.com/longyg/archive/2012/06/25/2561332.html https://www.cnblogs.com/qdwyg2013/p/5650764.html#top 引入jar包的maven依赖如下所示:

VBS实现批量重命名文件并且操作前备份原有文件

'=========================================================================='' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 4.0'' NAME: '' AUTHOR: Microsoft , Microsoft' DATE : 2014/7/9'' COMMENT: '批量修改文件夹下对应的所有文件名''==========

内存问题排查手段及相关文件介绍

5.内存问题排查手段及相关文件介绍[重点] 对于内存问题排查,或者OOM问题排查,一般会涉及到如下文件,下面将如下文件的分析和设置介绍一下,这也是本文档的重点,后面排查内存信息还是要根据这些文件信息来排查.其实未必是有内存泄露,也可能是一些策略有问题,比如线程数目的增加,buffer的申请.释放时间交集等. 5.1 /proc/sys/vm/min_free_kbytes min_free_kbytes用来确定系统开始回收内存的阀值,控制系统的空闲内存.值越高,内核越早开始回收内存,空闲内存越高

java操作office和pdf文件java读取word,excel和pdf文档内容

在平常应用程序中,对office和pdf文档进行读取数据是比较常见的功能,尤其在很多web应用程序中.所以今天我们就简单来看一下Java对word.excel.pdf文件的读取.本篇博客只是讲解简单应用.如果想深入了解原理.请读者自行研究一些相关源码. 首先我们来认识一下读取相关文档的jar包: 1. 引用POI包读取word文档内容 poi.jar 下载地址 http://apache.freelamp.com/poi/release/bin/poi-bin-3.6-20091214.zip 

面试- 阿里-. 大数据题目- 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?

假如每个url大小为10bytes,那么可以估计每个文件的大小为50G×64=320G,远远大于内存限制的4G,所以不可能将其完全加载到内存中处理,可以采用分治的思想来解决. Step1:遍历文件a,对每个url求取hash(url)%1000,然后根据所取得的值将url分别存储到1000个小文件(记为a0,a1,...,a999,每个小文件约300M); Step2:遍历文件b,采取和a相同的方式将url分别存储到1000个小文件(记为b0,b1,...,b999); 巧妙之处:这样处理后,所