如果数据很大且进程为32位,那么在使用.Net MemoryStream时出现内存不足异常的问题。
我相信System.IO.Packaging API会随着数据量的增加而从内存静默切换到文件支持的存储,从表面上看,似乎可以实现一个MemoryStream的子类。完全相同的事情。
有谁知道这样的实现?我很确定框架本身没有任何内容。
答案 0 :(得分:8)
程序员努力避免使用文件。在Windows中,内存和文件之间的差异非常小。用于MemoryStream的任何内存实际上都需要一个文件。存储由页面文件c:\ pagefile.sys支持。反之亦然,您使用的任何文件都由内存支持。文件数据由文件系统缓存缓存在RAM中。因此,如果机器有足够的RAM,那么如果使用FileStream,实际上只能从/向内存读写。并获得你期望使用内存的性能。它完全免费,您不必编写任何代码来启用此功能,也不必管理它。
如果机器没有足够的RAM,那么它会以同样的方式恶化。当您使用MemoryStream时,页面文件开始被废弃,您将被磁盘放慢速度。当您使用文件时,数据将不适合文件系统缓存,您将被磁盘放慢速度。
你当然会得到使用文件的好处,你不会再耗尽内存了。改为使用FileStream。
答案 1 :(得分:1)
预计这将使用MemoryStream
发生,因此您应该实现自己的逻辑或使用一些外部类。这是一篇解释MemoryStream
和大数据问题的帖子,帖子提供了MemoryStream
A replacement for MemoryStream
答案 2 :(得分:1)
我们在团队中遇到了类似的障碍。一些评论者建议开发人员在使用文件时需要更加安全。如果可以直接使用文件系统,则可以这样做,但这并不总是一种选择。
如果像我们需要的那样,希望在应用程序周围传递从文件读取的数据,则不能传递FileStream对象,因为它可以在读取数据之前被处理掉。我们最初使用MemoryStreams来使我们轻松传递数据,但是遇到了同样的问题。
我们使用了几种不同的解决方法来缓解该问题。
我们使用的选项包括:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
void save_texture(const char* file_name, SDL_Renderer* renderer, SDL_Texture* texture);
SDL_Texture* clipTexture(SDL_Rect rect, SDL_Renderer* renderer, SDL_Texture* source);
int main(int argc, const char * argv[])
{
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
SDL_Surface* surface = IMG_Load("test.png");
SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(surface);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect frame_rect = { 189, 243,115, 50 };
SDL_Texture* tex_clip = clipTexture( frame_rect, renderer, texture );
save_texture("test1.png", renderer, tex_clip);
SDL_FreeSurface(surface);
return 0;
}
// return a new texture that is a part of the original texture.
SDL_Texture* clipTexture(SDL_Rect rect, SDL_Renderer* renderer, SDL_Texture* source)
{
SDL_Texture* result = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET, rect.w, rect.h);
SDL_SetRenderTarget(renderer, result);
SDL_SetTextureBlendMode(source, SDL_BLENDMODE_NONE);
SDL_RenderCopy(renderer, source, &rect, NULL);
return result;
}
// save png to disk
void save_texture(const char* file_name, SDL_Renderer* renderer, SDL_Texture* texture)
{
int width, height;
SDL_QueryTexture(texture, NULL, NULL, &width, &height);
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask);
SDL_RenderReadPixels(renderer, NULL, surface->format->format, surface->pixels, surface->pitch);
IMG_SavePNG(surface, file_name);
SDL_FreeSurface(surface);
}
个条目)byte []对象中,并公开使您几乎可以将它们视为Stream的方法。我们仍然不惜一切代价避免这种情况。答案 3 :(得分:-1)
我建议查看这个项目。
http://www.codeproject.com/Articles/348590/A-replacement-for-MemoryStream
我认为内存流的问题来自这样一个事实:在它下面所有它们仍然是单个字节[]的花哨包装器,因此仍受.net要求所有对象即使在64位也必须小于2gb的要求程式。上面的实现将byte []分成几个不同的byte [] s。