swfbridge和大文件

时间:2010-11-30 23:18:22

标签: flash alchemy

我有一个与Alchemy一起使用的C项目。该项目有一些构建后的命令行测试,我想使用swfbridge运行。

这些测试运行,但它们非常慢。问题是他们将一些中等大小的文件(~3MB)读入内存。通过常规Alchemy使用相同的文件运行这些相同的测试(例如,不使用swfbridge但使用来自AS的supplyFile)非常快。

我认为瓶颈是swfbridge。更具体地说,就像swfbridge加载文件的方式一样。它读入它们并通过localhost连接以1024字节的块传输它们到主炼金术swf。 (你可以在swfbridge.log中看到这种情况。)

我的问题是:有没有办法让swfbridge更有效率?我可以使用不同的块大小,例如?

以下是文件读取代码的示例。如果你给这个代码一个~3MB的文件,它将慢慢地非常

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

size_t filesize(const char filename[]) {
    struct stat stbuf;
    if (stat(filename, &stbuf) == -1) {
        fprintf(stdout, "file_size: can't find %s\n...\n", filename);
        return (-1);
    }
    return stbuf.st_size;
}

int main(int argc, char **argv) {
    const char *filename= argv[1];
    size_t size= filesize(filename);

    printf("allocating %d bytes \n", size); fflush(stdout);
    char *data= (char*)malloc(size);

    printf("reading %d bytes \n", size); fflush(stdout);
    FILE *file= fopen(filename, "r");
    fread(data, size, 1, file);

    printf("done \n"); fflush(stdout);
    free(data);
    fclose(file);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

我想出了解决这个问题的方法。

当从命令行运行swf时,文件i / o非常慢,因为swf进程通过localhost套接字从swfbridge进程获取文件。关于这一点的东西没有得到优化(炼金术家们可能没想到任何人会以严肃的方式使用它)。使用swfbridge以便stdin和stdout可以工作。但我还不完全清楚为什么它用于文件i / o-- swf在adl(Air!)中运行 - 毕竟它有文件系统访问权限。

无论如何,可以使用swf在Air中运行的事实。我们可以使用精彩的funopen通过Air方法(而不是通过swfbridge)路由fread / fwrite。它实际上是一个很好的代码,但这里有一个想法:

FILE* air_fopen(const char filename[], const char mode[]) {
    AS3_Val file= AS3_FileFromPath(filename);

    AS3_Val FileModeClass= AS3_GetClass("flash.filesystem", "FileMode");
    AS3_Val fileMode     = AS3_GetS(FileModeClass, fopenModeToAirMode(mode));

    AS3_Val fileStream   = AS3_NewObject("flash.filesystem", "FileStream"); 
    AS3_CallTS("open", fileStream, "AS3ValType, AS3ValType", file, fileMode);

    AS3_Release(FileModeClass);
    AS3_Release(fileMode);  
    AS3_Release(file);

    return funopen(fileStream,
                   (funopen_read_t)air_fread, (funopen_write_t)air_fwrite,
                   (funopen_seek_t)air_fseek, (funopen_close)air_fclose);
} 

其中air_read是这样的:

int air_fread(AS3_Val fileStream, char *dest, int size) {
    int bytesAvailable= AS3_GetIntProperty(fileStream, "bytesAvailable");
    if (bytesAvailable <= 0) {
        return 0;
    } else if (size > bytesAvailable) {
        size= bytesAvailable;
    }

    AS3_CallTS("readBytes", fileStream, "AS3ValType, IntType, IntType", AS3_Ram(), dest, size);

    return size;
}

另一个air_fwrite / air_fweek / air_fclose是类似的。请注意,其中一些函数(如AS3_FileFromPath,AS3_GetInProperty,AS3_NewObject等)是我自己围绕AS3 api的简单包装器。

这种方法消除了swfbridge瓶颈,使命令行swfs与普通swfs一样快。