- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个访问 PostgreSQL 数据库的应用程序,需要根据某些需要的处理从中读取一些大型二进制数据。这可能是数百 MB 甚至几 GB 的数据。请不要讨论使用文件系统之类的,现在就是这样。
该数据只是各种类型的文件,例如它可能是一个 Zip 容器或某种其他类型的存档。一些需要的处理是列出 Zip 的内容,甚至可能提取一些成员进行进一步处理,可能对存储的数据进行哈希处理......最终数据被多次读取,但只写入一次以存储它。
我使用的所有 Perl 库都能够使用文件句柄,有些使用 IO::Handle
, 其他人与 IO::String
或 IO::Scalar
,其他一些仅具有低级文件句柄。所以我所做的是创建一个 IO::Handle
的子类和 IO::Seekable
它就像 DBD::Pg
周围相应方法的包装器.在 CTOR 中,我创建了一个到数据库的连接,打开一些提供的 LOID 用于读取并将 Postgres 提供的句柄存储在实例中。然后将我自己的句柄对象转发给能够使用此类文件句柄的任何人,并且可以直接在 Postgres 提供的 blob 中读取和查找。
问题是在 IO::Handle
上使用低级文件句柄或低级文件句柄操作的库。 . Digest::MD5
好像是一个,Archive::Zip
另一个。 Digest::MD5
croak
s 并告诉我没有提供句柄,Archive::Zip
另一方面,尝试从我的创建一个新的、自己的句柄,调用 IO::Handle::fdopen
在我的情况下失败。
sub fdopen {
@_ == 3 or croak 'usage: $io->fdopen(FD, MODE)';
my ($io, $fd, $mode) = @_;
local(*GLOB);
if (ref($fd) && "".$fd =~ /GLOB\(/o) {
# It's a glob reference; Alias it as we cannot get name of anon GLOBs
my $n = qualify(*GLOB);
*GLOB = *{*$fd};
$fd = $n;
} elsif ($fd =~ m#^\d+$#) {
# It's an FD number; prefix with "=".
$fd = "=$fd";
}
open($io, _open_mode_string($mode) . '&' . $fd)
? $io : undef;
}
IO::Handle
在需要低级文件句柄的任何地方都可以成功使用哪个?
IO::String
,另外使用
tie
例如。但最终这个用例是不同的,因为 Perl 能够自己创建一个真正的低级文件句柄到一些内部存储器。在我的情况下根本不支持的东西。我需要保留我的实例,因为只有它知道数据库的句柄等。
IO::Handle
一样使用我的 handle 通过调用方法
read
这样的工作就像预期的那样,但我想更进一步,并与那些不希望在
IO::Handle
上工作的人更加兼容。对象。很像
IO::String
或
File::Temp
可以用作低级文件句柄。
package ReadingHandle;
use strict;
use warnings;
use 5.10.1;
use base 'IO::Handle', 'IO::Seekable';
use Carp ();
sub new
{
my $invocant = shift || Carp::croak('No invocant given.');
my $db = shift || Carp::croak('No database connection given.');
my $loid = shift // Carp::croak('No LOID given.');
my $dbHandle = $db->_getHandle();
my $self = $invocant->SUPER::new();
*$self->{'dbHandle'} = $dbHandle;
*$self->{'loid'} = $loid;
my $loidFd = $dbHandle->pg_lo_open($loid, $dbHandle->{pg_INV_READ});
*$self->{'loidFd'} = $loidFd;
if (!defined($loidFd))
{
Carp::croak("The provided LOID couldn't be opened.");
}
return $self;
}
sub DESTROY
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
$self->close();
}
sub _getDbHandle
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
return *$self->{'dbHandle'};
}
sub _getLoid
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
return *$self->{'loid'};
}
sub _getLoidFd
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
return *$self->{'loidFd'};
}
sub binmode
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
return 1;
}
sub close
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
my $dbHandle = $self->_getDbHandle();
my $loidFd = $self->_getLoidFd();
return $dbHandle->pg_lo_close($loidFd);
}
sub opened
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
my $loidFd = $self->_getLoidFd();
return defined($loidFd) ? 1 : 0;
}
sub read
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
my $buffer =\shift // Carp::croak('No buffer given.');
my $length = shift // Carp::croak('No amount of bytes to read given.');
my $offset = shift || 0;
if ($offset > 0)
{
Carp::croak('Using an offset is not supported.');
}
my $dbHandle = $self->_getDbHandle();
my $loidFd = $self->_getLoidFd();
return $dbHandle->pg_lo_read($loidFd, $buffer, $length);
}
sub seek
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
my $offset = shift // Carp::croak('No offset given.');
my $whence = shift // Carp::croak('No whence given.');
if ($offset < 0)
{
Carp::croak('Using a negative offset is not supported.');
}
if ($whence != 0)
{
Carp::croak('Using a whence other than 0 is not supported.');
}
my $dbHandle = $self->_getDbHandle();
my $loidFd = $self->_getLoidFd();
my $retVal = $dbHandle->pg_lo_lseek($loidFd, $offset, $whence);
$retVal = defined($retVal) ? 1 : 0;
return $retVal;
}
sub tell
{
my $self = shift || Carp::croak('The method needs to be called with an instance.');
my $dbHandle = $self->_getDbHandle();
my $loidFd = $self->_getLoidFd();
my $retVal = $dbHandle->pg_lo_lseek($loidFd);
$retVal = defined($retVal) ? $retVal : -1;
return $retVal;
}
1;
最佳答案
有一种方法可以解决这个问题,但它有点奇怪。如果我正确阅读您的代码和评论,您的要求基本上是三重的:
Archive::Zip
合作,它主要在常规 Perl 中实现,并调用 IO::Handle::fdopen
您发布的代码无法复制句柄,因为它不是真正的句柄。 Digest::MD5
合作,这是在 XS 中使用 PerlIO 实现的.自 tie
-based 技巧和 perl 内存中的“假”文件句柄在该级别无法使用,它比 2 更技巧。PerlIO::via
来实现所有这三个目标。 .该代码类似于您使用
tie
编写的代码。 (实现一些必需的行为方法)。此外,您可以利用
open
的“将变量作为文件打开”功能。和预卷
IO::Seekable
+
IO::Handle
IO::File
的功能简化实现上述要求 1(使其在 Perl 代码中可用,与普通
IO::Handle
对象相同)。
lines
arrayref 作为文件数据。如果这看起来适合您的用例,您应该调整它以与数据库一起使用。 SEEK
、 EOF
、 BINMODE
、 SEEK
等一无所知)。请注意,您将要实现的函数的参数/预期行为与您为 tie
所做的不同。或 Tie::Handle
; “接口(interface)”具有相同的名称,但具有不同的契约。 *$self->{args}
中的所有自定义状态全局字段。这是因为受祝福的对象被创建了两次(一次被 PerlIO 祝福,一次被 SUPER::new
祝福),所以需要通过共享引用来共享状态。如果更换 args
字段或添加/删除任何其他字段,它们只会对创建它们的方法集可见:PerlIO 方法或“普通”对象方法。有关更多信息,请参阅构造函数中的注释。 sysread
这样的低级操作下出现问题或 <$fh>
,很多代码会出错或做意想不到的事情,因为它认为这些函数在操作级别无法死亡/原子化。类似地,当使用 PerlIO 时,故障模式很容易逃脱“死亡或返回错误值”的领域并最终进入“段错误或核心转储”的领域,特别是如果多个进程( fork()
)或线程是涉及(例如,这些奇怪的情况是为什么下面的模块没有在 IO::File->new;
后面跟着 $file->open(... "via:<($class)")
实现;它对我来说是核心转储,不知道为什么)。 TL;DR 调试为什么在 PerlIO 级别出错可能很烦人,你被警告了 :) Digest::MD5
不适用于捆绑的 handle ,因为它在“低于”的级别运行 tie
的魔法; PerlIO 比它“低”一个级别,但下面还有另一个级别。 open()
好一些。直接分层对象,跳过所有奇怪的伪间接对象内容,然后将其包装在 IO::Handle 中以其他方式,例如通过 IO::Wrap
. package TiedThing;
use strict;
use warnings;
use parent "IO::File";
our @pushargs;
sub new {
my ( $class, $args ) = @_;
# Build a glob to be used by the PerlIO methods. This does two things:
# 1. Gets us a place to stick a shared hashref so PerlIO methods and user-
# -defined object methods can manipulate the same data. They must use the
# {args} glob field to do that; new fields written will .
# 2. Unifies the ways of addressing that across custom functions and PerlIO
# functions. We could just pass a hashref { args => $args } into PUSHED, but
# then we'd have to remember "PerlIO functions receive a blessed hashref,
# custom functions receive a blessed glob" which is lame.
my $glob = Symbol::gensym();
*$glob->{args} = $args;
local @pushargs = ($glob, $class);
my $self = $class->SUPER::new(\my $unused, "<:via($class)");
*$self->{args} = $args;
return $self;
}
sub custom {
my $self = shift;
return *$self->{args}->{customvalue};
}
sub PUSHED { return bless($pushargs[0], $pushargs[1]); }
sub FILL { return shift(@{*$_[0]->{args}->{lines}}); }
1;
my $object = TiedThing->new({
lines => [join("\n", 1..9, 1..9)],
customvalue => "custom!",
});
say "can call custom method: " . $object->custom;
say "raw read with <>: " . <$object>;
my $buf;
read($object, $buf, 10);
say "raw read with read(): " . $buf;
undef $buf;
$object->read($buf, 10);
say "OO read via IO::File::read (end): " . $buf;
my $checksummer = Digest::MD5->new;;
$checksummer->addfile($object);
say "Md5 read: " . $checksummer->hexdigest;
my $dupto = IO::Handle->new;
# Doesn't break/return undef; still not usable without implementing
# more state sharing inside the object.
say "Can dup handle: " . $dupto->fdopen($object, "r");
my $archiver = Archive::Zip->new;
# Dies, but long after the fdopen() call. Can be fixed by implementing more
# PerlIO methods.
$archiver->readFromFileHandle($object);
关于postgresql - 如何在没有文件或内存的情况下对 IO::Handle 进行子类化以正确获取低级文件句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40377263/
今天我在一个 Java 应用程序中看到了几种不同的加载文件的方法。 文件:/ 文件:// 文件:/// 这三个 URL 开头有什么区别?使用它们的首选方式是什么? 非常感谢 斯特凡 最佳答案 file
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我有一个 javascript 文件,并且在该方法中有一个“测试”方法,我喜欢调用 C# 函数。 c# 函数与 javascript 文件不在同一文件中。 它位于 .cs 文件中。那么我该如何管理 j
需要检查我使用的文件/目录的权限 //filePath = path of file/directory access denied by user ( in windows ) File fil
我在一个目录中有很多 java 文件,我想在我的 Intellij 项目中使用它。但是我不想每次开始一个新项目时都将 java 文件复制到我的项目中。 我知道我可以在 Visual Studio 和
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我有 3 个组件的 Twig 文件: 文件 1: {# content-here #} 文件 2: {{ title-here }} {# content-here #}
我得到了 mod_ldap.c 和 mod_authnz_ldap.c 文件。我需要使用 Linux 命令的 mod_ldap.so 和 mod_authnz_ldap.so 文件。 最佳答案 从 c
我想使用PIE在我的项目中使用 IE7。 但是我不明白的是,我只能在网络服务器上使用 .htc 文件吗? 我可以在没有网络服务器的情况下通过浏览器加载的本地页面中使用它吗? 我在 PIE 的文档中看到
我在 CI 管道中考虑这一点,我应该首先构建和测试我的应用程序,结果应该是一个 docker 镜像。 我想知道使用构建环境在构建服务器上构建然后运行测试是否更常见。也许为此使用构建脚本。最后只需将 j
using namespace std; struct WebSites { string siteName; int rank; string getSiteName() {
我是 Linux 新手,目前正在尝试使用 ginkgo USB-CAN 接口(interface) 的 API 编程功能。为了使用 C++ 对 API 进行编程,他们提供了库文件,其中包含三个带有 .
我刚学C语言,在实现一个程序时遇到了问题将 test.txt 文件作为程序的输入。 test.txt 文件的内容是: 1 30 30 40 50 60 2 40 30 50 60 60 3 30 20
如何连接两个tcpdump文件,使一个流量在文件中出现一个接一个?具体来说,我想“乘以”一个 tcpdump 文件,这样所有的 session 将一个接一个地按顺序重复几次。 最佳答案 mergeca
我有一个名为 input.MP4 的文件,它已损坏。它来自闭路电视摄像机。我什么都试过了,ffmpeg , VLC 转换,没有运气。但是,我使用了 mediainfo和 exiftool并提取以下信息
我想做什么? 我想提取 ISO 文件并编辑其中的文件,然后将其重新打包回 ISO 文件。 (正如你已经读过的) 我为什么要这样做? 我想开始修改 PSP ISO,为此我必须使用游戏资源、 Assets
给定一个 gzip 文件 Z,如果我将其解压缩为 Z',有什么办法可以重新压缩它以恢复完全相同的 gzip 文件 Z?在粗略阅读了 DEFLATE 格式后,我猜不会,因为任何给定的文件都可能在 DEF
我必须从数据库向我的邮件 ID 发送一封带有附件的邮件。 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Adventure Works Admin
我有一个大的 M4B 文件和一个 CUE 文件。我想将其拆分为多个 M4B 文件,或将其拆分为多个 MP3 文件(以前首选)。 我想在命令行中执行此操作(OS X,但如果需要可以使用 Linux),而
快速提问。我有一个没有实现文件的类的项目。 然后在 AppDelegate 我有: #import "AppDelegate.h" #import "SomeClass.h" @interface A
我是一名优秀的程序员,十分优秀!