あおきです。
In Mail "[ruby-list:15857] Re: maillib with big base64"
kikutani / sprintmail.com wrote:
> > ないはずです。小さくすると送れるということは、たぶんサイズが
> > 原因でしょう。想像するに、行末コードが\rとかになっているのでは?
> > あるいは、\r\nの環境で\nの場合でも同様です。
> > そうすると、eachループの一回目で一気に全部読み込まれて、3MBの
> > 文字列にgsub!をかけることになるので、すさまじい負荷がかかります。
>
> 行末は \n ですが、送れないのはたかだか8KBくらいです。
あ、外れでしたか。すみません。
> > 望ましいと思います。sendmailなど、巨大な文字列を扱う可能性のある
> > メソッドはどれも引数からeachを介して文字列を受けとることになって
> > いるので、文字列やIOにラッパーをかぶせてやるのがいいです。
>
> 具体的にはどういうラッパーですか?
…よく考えると文字列じゃあだめですね。IOじゃないと。# ボケたか?
例えばこんな(↓)感じに、確実に一行づつ渡るようにすればOKです。
class Buffer
def initialize( f )
@src = f
end
BLOCKSIZE = 512
TERMEXP = /\n|\r\n|\r/o
def each
buf = ''
fin = false
while true do
begin
buf << @src.sysread( BLOCKSIZE )
rescue EOFError
break
end
begin
while buf[-1,1] == "\r" do # for \r\n
buf << @src.sysread(1)
end
rescue EOFError
end
beg = 0
pos = nil
while pos = buf.index( TERMEXP, beg ) do
pos += $&.size
yield buf[ beg, pos - beg ]
beg = pos
end
buf = buf[ beg, buf.size - beg ]
end
yield buf if buf.size > 0
end
end
同じようなコードを過去に10回くらい書いた覚えが… ^^;;
-------------------------------------------------------------------
あおきみねろう site: http://www1.u-netsurf.ne.jp/~brew/mine/jp/