diff --git a/ChangeLog b/ChangeLog
index 8491624..90c84aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
= Revision history for nuggets
+== 1.4.0 [unreleased]
+
+* Added File.open_file.
+
== 1.3.0 [2015-07-07]
* Added Hash.{identity,array}.
diff --git a/lib/nuggets/file/open_file.rb b/lib/nuggets/file/open_file.rb
new file mode 100644
index 0000000..01943d9
--- /dev/null
+++ b/lib/nuggets/file/open_file.rb
@@ -0,0 +1,5 @@
+require 'nuggets/file/open_file_mixin'
+
+class File
+ extend Nuggets::File::OpenFileMixin
+end
diff --git a/lib/nuggets/file/open_file_mixin.rb b/lib/nuggets/file/open_file_mixin.rb
new file mode 100644
index 0000000..e44c26f
--- /dev/null
+++ b/lib/nuggets/file/open_file_mixin.rb
@@ -0,0 +1,71 @@
+#--
+###############################################################################
+# #
+# nuggets -- Extending Ruby #
+# #
+# Copyright (C) 2007-2015 Jens Wille #
+# #
+# Authors: #
+# Jens Wille #
+# #
+# nuggets is free software; you can redistribute it and/or modify it under #
+# the terms of the GNU Affero General Public License as published by the Free #
+# Software Foundation; either version 3 of the License, or (at your option) #
+# any later version. #
+# #
+# nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with nuggets. If not, see . #
+# #
+###############################################################################
+#++
+
+module Nuggets
+ class File
+ module OpenFileMixin
+
+ # call-seq:
+ # File.open_file(filename[, options[, mode]]) -> anIO
+ # File.open_file(filename[, options[, mode]]) { |io| ... } => anObject
+ #
+ # Supported options are +mode+ (defaults to +r+) and +encoding+ (defaults
+ # to the default external encoding).
+ #
+ # If +filename+ is +-+, sets +io+ to +STDOUT+ when in write mode or +STDIN+
+ # otherwise. Puts +io+ into binary mode if requested. Sets +io+'s encoding.
+ #
+ # If +filename+ ends with +.gz+ or +.gzip+, uses Zlib for reading or writing
+ # the file.
+ #
+ # Otherwise defers to ::open.
+ #
+ # Yields +io+ to the given block or returns it when no block given.
+ def open_file(filename, options = {}, mode = 'r', &block)
+ mode = options.fetch(:mode, mode); writing = mode =~ /w/
+
+ encoding = options.fetch(:encoding, ::Encoding.default_external)
+
+ case filename
+ when '-'
+ io = writing ? $stdout : $stdin
+ io.binmode if mode =~ /b/
+ io.set_encoding(encoding)
+
+ block ? block[io] : io
+ when /\.gz(?:ip)?\z/i
+ require 'zlib'
+
+ klass = writing ? ::Zlib::GzipWriter : ::Zlib::GzipReader
+ klass.open(filename, encoding: encoding, &block)
+ else
+ open(filename, mode, encoding: encoding, &block)
+ end
+ end
+
+ end
+ end
+end