Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File unix在没有缓冲区/复制的情况下将行预结束到文件_File_Unix_Sed - Fatal编程技术网

File unix在没有缓冲区/复制的情况下将行预结束到文件

File unix在没有缓冲区/复制的情况下将行预结束到文件,file,unix,sed,File,Unix,Sed,我想要这个,sed解决方案看起来不错,但当我尝试时,它似乎创建了一个巨大的临时文件 我有一个很大的sql文件,大约28 Gig,我在文件系统上没有太多空间,只想在文件前面加一行。如何在不占用更多文件空间的情况下执行此操作?使用gcc编译: #include <stdio.h> #include <string.h> #include <malloc.h> // Prepend size must be less than this value #defin

我想要这个,sed解决方案看起来不错,但当我尝试时,它似乎创建了一个巨大的临时文件

我有一个很大的sql文件,大约28 Gig,我在文件系统上没有太多空间,只想在文件前面加一行。如何在不占用更多文件空间的情况下执行此操作?

使用gcc编译:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

// Prepend size must be less than this value
#define bufSize 1024000

int main( int argc, char **argv )
{
    FILE *fil;
    unsigned char *smallBuf, *mainBuf;
    size_t sReadSize, mReadSize;
    long readPos = 0, writePos = 0;
    int appendSize;

    if( argc != 3 )
    {
        printf( "Usage: %s, <prepend_line> <file>\n", argv[0] );
        return 1;
    }

    sReadSize = appendSize = strlen( argv[1] ) + 1;

    smallBuf = (unsigned char *) malloc( appendSize );
    mainBuf = (unsigned char *) malloc( bufSize );
    if( !smallBuf || !mainBuf )
    {
        printf( "No memory\n" );
        return 1;
    }

    memcpy( smallBuf, argv[1], appendSize );
    smallBuf[ appendSize - 1 ] = '\n';

    fil = fopen( argv[2], "rb+" );
    if( !fil )
    {
        printf( "Cannot open file\n" );
        return 1;
    }

    while( 1 )
    {
        fseek( fil, readPos, 0 );
        readPos += mReadSize = fread( mainBuf, 1, bufSize, fil );

        fseek( fil, writePos, 0 );
        writePos += fwrite( smallBuf, 1, sReadSize, fil );

        if( mReadSize < bufSize )
        {
            if( mReadSize > 0 )
                fwrite( mainBuf, 1, mReadSize, fil );
            break;
        }

        fseek( fil, readPos, 0 );
        readPos += sReadSize = fread( smallBuf, 1, appendSize, fil );

        fseek( fil, writePos, 0 );
        writePos += fwrite( mainBuf, 1, mReadSize, fil );

        if( sReadSize < appendSize )
        {
            if( sReadSize > 0 )
                fwrite( smallBuf, 1, sReadSize, fil );
            break;
        }
    }

    fclose( fil );
    return 0;
}
#包括
#包括
#包括
//前置大小必须小于此值
#定义bufSize 1024000
int main(int argc,字符**argv)
{
文件*fil;
无符号字符*smallBuf,*mainBuf;
大小\u t sReadSize,mReadSize;
long readPos=0,writePos=0;
int-appendSize;
如果(argc!=3)
{
printf(“用法:%s\n”,argv[0]);
返回1;
}
sReadSize=appendSize=strlen(argv[1])+1;
smallBuf=(无符号字符*)malloc(appendSize);
mainBuf=(无符号字符*)malloc(bufSize);
如果(!smallBuf | |!mainBuf)
{
printf(“无内存”);
返回1;
}
memcpy(smallBuf,argv[1],appendSize);
smallBuf[appendSize-1]='\n';
fil=fopen(argv[2],“rb+”);
如果(!fil)
{
printf(“无法打开文件\n”);
返回1;
}
而(1)
{
fseek(fil,readPos,0);
readPos+=mReadSize=fread(mainBuf,1,bufSize,fil);
fseek(fil,writePos,0);
writePos+=fwrite(smallBuf,1,sReadSize,fil);
如果(mReadSize0)
fwrite(mainBuf,1,mReadSize,fil);
打破
}
fseek(fil,readPos,0);
readPos+=sReadSize=fread(smallBuf,1,appendSize,fil);
fseek(fil,writePos,0);
writePos+=fwrite(mainBuf,1,mReadSize,fil);
如果(sReadSize0)
fwrite(smallBuf,1,sReadSize,fil);
打破
}
}
fclose(fil);
返回0;
}

不幸的是,在我见过的每一个操作系统和文件系统上,预结束通常都不能像附加can那样进行。有人可能会说,如果数据量是底层文件系统块大小的几倍,那么文件系统可以有效地实现这一点,但由于通常情况并非如此,我不知道有哪一个系统实际实现了这种功能。因此,可能唯一的方法是通过临时文件或副本。但是,您可以使用压缩来在某种程度上缓解空间紧张,但这需要一些准备工作,并且最终可能并不合适。大致如下:

1) gzip original_file.sql    # or bzip2 or whatever
2) create new_file.sql with data to be prepended
3) (cat new_file.sql; zcat original_file.sql.gz) | gzip > updated_file.sql.gz
4) zcat updated_file.sql.gz | less  # inspect the top of the file to make sure it looks right
5) rm original_file.sql.gz new_file.sql
6) gunzip updated_file.sql.gz # if necessary to have uncompressed text available - if not, just leave it compressed

您可以使用perl进行以下操作:

perl -i -n -e 'print "xxx\n$_" if $.==1;print if $.!=1' your_file

您是否可以将这一行放在单独的文件中,然后使用读取数据的
cat单行文件28 GB文件|程序
?这避免了在磁盘上显式创建文件。我有两个缓冲区,第一个是读1块,第二个是写前置,第二个是读,第一个是写,。。。请多加注意。是的,我仔细检查后发现了。我将编辑原始注释,但我仍会注意到这是一个危险的操作,特别是当原始问题是关于多GB文件时。在断电、程序意外提前终止或任何其他因素的情况下,就地修改容易发生灾难性故障,这将导致文件的唯一副本部分修改(尽管可能至少以某种程度上可预测的方式,忽略缓存/写回计时问题)约利奥先生提出了一个不需要额外记忆的简单建议。当然,通过添加包含缓冲区内容和当前进度信息的临时文件,它可能具有容错性。
-i
在后台使用临时文件。尽管不是我所寻找的答案,但似乎是正确的,并且达成了共识。