这边继续是关于那个读取txt文件的频率增加的问题,这边的C++封装继续改善后发觉系统稳定了,感谢john的不懈努力和完善精神,发觉自己已经被生活磨去了很多专研精神,这边先上C语言的封装代码:
其次,quotation的delete也是让内存泄露不再发生,同时也避免了野指针:
同时调用这段也做了一些调整, 主要是Marshal.FreeHGlobal来析构这个堆栈以及使用throw来抛出万一这个c的封装有异常抛出,这样不会让服务异常当机。
</pre><pre name="code" class="cpp">
// OptionsPlay.SharedFile.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <stdio.h>
#include <sys\timeb.h>
#include <stdlib.h>
#include<windows.h>
//#define LINENUM 174
#define LINESIZE 428
#define TESTTIME 100
#define _CRT_SECURE_NO_DEPRECATE
extern "C"_declspec(dllexport) int ReadSharedFolder(char *p, const char*targetFile, int lineNum);
void resetLoc(int *loc)
{
*loc = 0;
}
int ReadSharedFolder(char *p, const char*targetFile, int lineNum){
FILE *fp = fopen(targetFile, "r");
if (fp == NULL)
{
perror("Error opeing file");
return -1;
}
// manual initial one-dimension array p
for (int i = 0; i < lineNum * (LINESIZE - 1); i++){
p[i] = '\0';
}
// initialize two-dimension array quotation
char **quotation;
quotation = new char*[lineNum];
for (int j = 0; j < lineNum; j++){
quotation[j] = new char[LINESIZE];
}
int loc = 0;
while (fgets(quotation[loc], LINESIZE, fp) != NULL)
{
loc++;
}
for (int i = 1; i < loc - 1; i++){
for (int j = 0; j < (LINESIZE - 1); j++){
p[(i - 1) * (LINESIZE - 1) + j] = quotation[i][j];
}
}
fclose(fp);
//resetLoc(&loc);
// free array quotation
for (int i = 0; i < lineNum; i++){
delete[] quotation[i];
quotation[i] = NULL;
}
delete[] quotation;
return 0;
}
首先这个代码用来填充/0很关键,否则会有缓冲区的不释放的乱码存在,比如/r/n之类的:
for (int i = 0; i < lineNum * (LINESIZE - 1); i++){
p[i] = '\0';
}
其次,quotation的delete也是让内存泄露不再发生,同时也避免了野指针:
for (int i = 0; i < lineNum; i++){
delete[] quotation[i];
quotation[i] = NULL;
}
delete[] quotation;
同时调用这段也做了一些调整, 主要是Marshal.FreeHGlobal来析构这个堆栈以及使用throw来抛出万一这个c的封装有异常抛出,这样不会让服务异常当机。
[DllImport("OptionsPlay.SharedFile.dll", EntryPoint = "ReadSharedFolder", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern int ReadSharedFolder(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string targetFile, int lineNum);
public static byte[] GetData(string folder, string fileName, int lineNum, int filetypeFlag)
{
IntPtr p = System.IntPtr.Zero;
try
{
if (filetypeFlag == 1)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
p = Marshal.AllocHGlobal(sizeof(char) * lineNum * lineSize);
if (ReadSharedFolder(p, fileName, lineNum) == -1)
{
Logger.Debug(string.Format("Error opening file ", fileName, stopwatch.ElapsedMilliseconds));
throw new System.IO.IOException("error opening txt file");
}
byte[] b = new byte[lineNum * lineSize];
Marshal.Copy(p, b, 0, lineNum * lineSize);
stopwatch.Stop();
Logger.Debug(string.Format("File {0} Copied in {1}ms", fileName, stopwatch.ElapsedMilliseconds));
return b;
}
else
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
string path = Path.Combine(folder, fileName);
byte[] result = File.ReadAllBytes(path);
stopwatch.Stop();
Logger.Debug(string.Format("File {0} Copied in {1}ms", fileName, stopwatch.ElapsedMilliseconds));
return result;
}
}
catch (Exception ex)
{
Logger.Error("FromLocalDrive GetData Error", ex);
throw;
}
finally
{
Marshal.FreeHGlobal(p);
}
}