Question: Is saying a cache is a special kind of buffer correct? They both perform similar functions, but is there some underlying difference that I am missing?

Answer: 
From Wikipedia's article on [data buffers](http://en.wikipedia.org/wiki/Data_buffer):

> 
> a buffer is a region of a physical memory storage used to temporarily hold data while it is being moved from one place to another
> 
> 
> 

A **buffer** ends up cycling through and holding every single piece of data that is transmitted from one storage location to another (like when using a circular buffer in audio processing). A buffer allows just that - a "buffer" of data before and after your current position in the data stream.

Indeed, there are some common aspects of a buffer and a cache. However, cache in the conventional sense usually does *not* store all of the data when it's being moved from place to place (i.e. CPU cache).

The purpose of a **[cache](http://en.wikipedia.org/wiki/Cache_%28computing%29)** is to store data in a transparent way, such that just enough data is cached so that the remaining data can be transferred without any performance penalty. In this context, the cache only "pre-fetches" a small amount of data (depending on the transfer rates, cache sizes, etc...).

The main difference is that a buffer will eventually have held all of the data. Conversely, a cache may have held all, some, or none of the data (depending on the design). However, a cache is accessed as if you were directly accessing the data in the first place - what exactly gets cached is transparent to the "user" of the cache.

---

The difference is in the *interface*. When you're using a cache to access a data source, you use it as if the cache **is** the data source - you can access every part of the data source through the cache, and the cache will determine where the data comes from (the cache itself, or the source). The cache itself determines what parts of the data to preload (usually just the beginning, but sometimes all), while the [cache replacement algorithm](http://en.wikipedia.org/wiki/Cache_algorithms) in use determines what/when things are removed from the cache. The best example of this is a system, aside from [CPU cache](http://en.wikipedia.org/wiki/CPU_cache) itself, is [prefetcher](http://en.wikipedia.org/wiki/Prefetcher)/[readahead](http://en.wikipedia.org/wiki/Readahead). Both load the parts of data they think you will use most into memory, and revert to the hard drive if something isn't cached.

Conversely, a buffer can't be used to instantaneously move your location in the data stream, unless the new part has already been moved to the buffer. To do so would require the buffer to relocate (given the new location exceeds the buffer length), effectively requiring you to "restart" the buffer from a new location. The best example of this is moving the slider in a Youtube video.

Another good example of a buffer is playing audio back in Winamp. Since audio files need to be decoded by the CPU, it takes some time between when the song is read in, to when the audio is processed, to when it's sent to your sound card. Winamp will buffer some of the audio data, so that there is enough audio data already processed to avoid any "lock-ups" (i.e. the CPU is always preparing the audio you'll hear in a few hundred milliseconds, it's never real-time; what you hear comes from the buffer, which is what the CPU prepared in the past).
Common thing: both are intermediary data storage components (software or hardware) between computation and "main" storage.

To me difference is the following:

Buffer:

* Handles **sequential** access to data (e.g. reading/writing data from file or socket)
* **Enables** interface between computation and main storage, **adapts** to each other the different data transfer patterns of a data producer and a data consumer. E.g. computation writes small chuncks of data, but disk drive can accept only pieces of data of a specific size. So the buffer accumulates small pieces as the input and regroup them into bigger pieces of the output.
* So it is like a **Adapter** design pattern. It joins two interacting components that cannot interoperate directly.
* Examples: disk buffer, BufferedReader in Java language, duffering in computer graphics.

Cache:

* Handles **random** access to data (e.g. CPU cache caches lines of mememory that located non necessary sequentially).
* **Optimizes** access to the main storage, makes it faster. E.g. CPU cache avoid accesses to memory thus making CPU commands faster.
* It is like a **Decorator** design pattern. It joins (often transparently) two interacting components that could in principle interoperate directly , but it makes the interaction faster.
* Examples: CPU cache, page cache, web proxy, browser cache.