<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ファイル操作 | hgrs&#039;s Blog</title>
	<atom:link href="/archives/tag/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%93%8D%E4%BD%9C/feed" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>文字好きエンジニアの技術メモ</description>
	<lastBuildDate>Sun, 12 Apr 2020 15:04:37 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.3.1</generator>

<image>
	<url>/wp-content/uploads/2019/05/cropped-port_512-32x32.png</url>
	<title>ファイル操作 | hgrs&#039;s Blog</title>
	<link>/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Pythonでオンメモリストリームを利用して、中間データを保存せずファイルを扱う</title>
		<link>/archives/286.html</link>
					<comments>/archives/286.html#respond</comments>
		
		<dc:creator><![CDATA[hgrs]]></dc:creator>
		<pubDate>Sat, 25 May 2019 14:18:34 +0000</pubDate>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[ファイル操作]]></category>
		<guid isPermaLink="false">/?p=286</guid>

					<description><![CDATA[はじめに フォントを軽量化するWebアプリを作った際に、サーバ側で3つのファイルをzipにしてダウン...]]></description>
										<content:encoded><![CDATA[<h2>はじめに</h2>
<p><a href="/20190522140056">フォントを軽量化するWebアプリ</a>を作った際に、サーバ側で3つのファイルをzipにしてダウンロードさせるということをしました。この時、サーバ側のストレージには保存できないのでファイルを保存せずに、データを送る必要があったので、そんなときの方法です。</p>
<h2>Pythonでのストリーム</h2>
<p>まず、ドキュメントは<a href="https://docs.python.org/ja/3/library/io.html">こちら</a>です。</p>
<p>Pythonでストリームを扱うモジュールは<code>io</code>です。特に、ファイルをストレージに保存せずにオンメモリで扱えるストリームには、文字列を扱う<code>io.StringIO</code>と、バイナリを扱う<code>io.BytesIO</code>の2種類があります。</p>
<p>ローカルで何かやる場合は、中間ファイルなども逐一保存して、デバッグなどに利用するかもしれませんが、本番環境で全て保存してたら、ストレージの容量がなくなってくので（特にフォントみたいに重めのデータや複数ファイルの場合）、オンメモリのストリームをうまく活用していきましょう。</p>
<h2>実際に使ってみる</h2>
<h3>テキストモードファイルのように扱う</h3>
<p>まず、<code>StringIO</code>です。これを使うことで、普通の文字列を、<code>open</code>で開いたテキストファイルのように扱うことができるようになります。</p>
<p>実際のコードがこちらです。</p>
<pre><code class="language-python">from io import StringIO

with StringIO() as bs:
    bs.write(&#039;こんにちは世界\n&#039;)
    bs.write(&#039;さよなら世界&#039;)
    content = bs.getvalue()

print(type(content))
print(content)</code></pre>
<p>これの出力結果はこちらです。</p>
<pre><code class="language-bash">&lt;class &#039;str&#039;&gt;
こんにちは世界
さよなら世界</code></pre>
<p>ファイルストリームと同様に<code>write</code>を使い、文字列を書き込んでいくことができます。そして最終的な文字列を得るためには<code>getvalue</code>を使います。これにより得られるのは文字列（<code>str</code>）です。</p>
<h3>バイナリモードファイルのように扱う</h3>
<p>次に、<code>BytesIO</code>です。これを扱うと、様々なバイナリファイルをオンメモリで扱うことができるようになります。</p>
<p>実際のコードがこちらです。動作の確認のため、最後に結局ファイルとして保存するとかいう本末転倒なことしてますが、これぐらいしかみて取れる確認方法がなかったので、許してください。</p>
<pre><code class="language-python">from io import BytesIO
from PIL import Image

with BytesIO() as bs:
    img = Image.new(&#039;L&#039;, (512, 512), 0)
    img.save(bs, &#039;png&#039;)
    content = bs.getvalue()

with open(&#039;img.png&#039;, mode=&#039;wb&#039;) as fs:
    fs.write(content)</code></pre>
<p>画像とかが見てわかりやすいかなと思ったので、画像を保存してみました。<code>BytesIO</code>で作成したオブジェクトにPillowの<code>save</code>を使って、画像を保存します。ただ、この時点ではまだ、メモリ上に存在しています。</p>
<p>これを普通のファイルのように様々なライブラリ等に渡すこともできますが、今回は単純に保存するため、<code>open</code>で<code>write</code>します。</p>
<p>すると同じディレクトリに<code>img.png</code>という真っ黒な画像の出来上がりです。</p>
<h2>おわりに</h2>
<p>中間ファイルを保存せずに扱えるのは便利ですね。</p>
<p>zipにするのはまたちょっとややこしいので、別で書こうと思います。</p>
]]></content:encoded>
					
					<wfw:commentRss>/archives/286.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
