Why is there a difference between text and binary files in Windows?
In reality, I'd assume that there's literally no difference between a text and a binary file in reality, as both are simply a collection of bytes. A text file may be easily representable [sic] in an editor depending on the encoding whereas a binary file generally won't be, but the underlying representation is the same: a sequence of bytes in a given order.
As you said, a file is just a bunch of bytes. That’s it. Its contents only take on meaning when interpreted by a program. It is entirely possible for one program to interpret the bytes in a file one way and another program to interpret them another. When you open a “binary” file in a text-editor, it will interpret the bytes as text and display them. If the file is not “plain text”, then the results will likely be gibberish, but the program is still doing its job of interpreting and outputting them.
In many different programming languages, there are constructs in place to specifically work around the fact that Windows differentiates between text and binary files.
Windows does not. What is happening is that most such programming languages evolved on other operating systems like Unix, Linux, etc. and therefore use different line-endings for native plain-text files. It is possible that they also use a different encoding, but it is usually the line-endings that will vary from platform to platform.
Here is a list of common platforms and line-endings:
- Unix, Linux - line-feed
- Windows - carriage-return, line-feed
- Mac (historically) - carriage-return
- (A few, old OSes (e.g., Acorn BBC) - line-feed, carriage return)
Why does Windows make this distinction which is seemingly unnecessary?
Windows is an operating system, it does not distinguish anything itself. The question you should ask is which parts of Windows are distinguishing. In this case, it is the command-prompt that treats text and binary files differently, and even then, it depends on the command being used. For example, the command
del foobar.txt is no different than
del foobar.bin, however
copy a.txt + b.txt c.txt is different from
copy /b a.bin + b.bin c.bin Why? Because the Windows command-prompt wants to be helpful and interprets text files as such and copies the lines to the output (adding a newline between files), but copies binary files as is with no interference.
For example, in Ruby:
f = File.open('filename.bin', 'rb') # read a file in binary mode
f = File.open('filename.txt', 'r') # read a file in text mode
f = open("filename.bin", "rb") # read a file in binary mode
f = open("filename.txt", "r") # read a file in text mode
On other operating systems, it seems that there's no difference between a text file and a binary file with the filesystem.
Those are all scripting languages, and therefore run from the command-line. When working with text input files, there is usually not much of a problem, but with binary files, you use the binary-mode to avoid the command prompt from pre-processing the file and passing it as raw bytes.
In Linux, when you type or pipe a file, the shell passes all the raw bytes instead of pre-processing it as text like the Windows command-prompt does.
That said, depending on the program and how the input file is passed, then it could easily avoid the pre-processing altogether. For example
C:\>pyhton foobar.py baz.bin would pass the name of the input file to the script which would then open it as it likes whereas
C:\>type baz.bin | python foobar.py would cause the command-prompt to read the file, then pass each line to the script, which for a binary file is no good.
The different modes simply allow for flexibility and allow you to play it safe and treat files like what you expect them to be.