2010-09-06 116 views
0

如何从数据库中提取二进制数据文件提取二进制数据保存到文件

CREATE TABLE `mail_attachs` (
    `attachid` int(15) NOT NULL auto_increment, 
    `filecontent` longtext, 
    PRIMARY KEY (`attachid`), 
) ENGINE=MyISAM 

二进制数据被保存在filecontent列。我想提取保存在该列中的文件和文本,并将其保存到同一台服务器上的文件中。 文件名将包含attachid,以便我可以识别和关联在数据库中找到的记录。

回答

1

你跟“perl的”太标记这文件,所以这里是一个Perl的解决方案。 “BETWEEN”子句是一次只能处理大量数据的简单方法,因为selectall_arrayref调用将(在当前版本的DBI模块下)将您要求的所有数据加载到内存中。

mysql> insert into mail_attachs values (1, 'abc'), (2, 'def'); 
Query OK, 2 rows affected (0.00 sec) 
Records: 2 Duplicates: 0 Warnings: 0 

$ cat extract.pl 
#!/usr/bin/perl 
use strict; 
use warnings; 
use DBI; 
my $output_dir = '/home/jmccarthy/mail_attachs'; 
my $dbh = DBI->connect_cached("DBI:mysql:database=test;host=dbmachine", 
    'username', 'password'); 
die "cannot connect, $DBI::err" if ! $dbh; 
my $rows = $dbh->selectall_arrayref("SELECT attachid, filecontent FROM mail_attachs 
    WHERE attachid BETWEEN ? AND ?", 
    { Slice => {} }, # get back better-self-documenting hashrefs, instead of arrayrefs 
    1, 1000); # values for the ?'s above 
die "selectall_arrayref failed, $DBI::err" if $DBI::err; 
for my $row (@$rows) { 
    open my $fh, '>', "$output_dir/file$row->{attachid}" 
     or die "cannot write $row->{attachid}, $!"; 
    print $fh $row->{filecontent} 
     or die "cannot print to $row->{attachid}, $!"; 
    close $fh 
     or die "cannot close $row->{attachid}, $!"; 
    print "wrote $row->{attachid}\n"; 
} 

$ ./extract.pl 
wrote 1 
wrote 2 

$ head mail_attachs/file* 
==> mail_attachs/file1 <== 
abc 
==> mail_attachs/file2 <== 
def