How to prevent that CR and LF are changed when writing bytes to file?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If you need bytes written exactly as they exist in memory, newline translation must be disabled. The usual cause of changed line endings is opening a file in text mode, because text APIs may convert \n into the platform default sequence such as \r\n on Windows.
Write in Binary Mode
The safest rule is simple: if the data is already bytes, use a byte-oriented API. In Python that means opening the file with wb or ab, not w or a.
That code writes the byte sequence exactly as given. Python does not reinterpret line endings in binary mode.
You can confirm the bytes after writing:
If the result is True, the file contents were preserved byte for byte.
Why Text Mode Changes Newlines
Text mode is designed for characters, not raw bytes. When you write a string, the runtime may apply encoding rules and newline normalization. That behavior is convenient for ordinary text files but wrong for protocols, fixtures, binary payloads, or test cases where exact line endings matter.
For example:
On some systems, that file may contain \n exactly as written. On Windows, the runtime can translate each newline to \r\n depending on the API and parameters. That is why byte-sensitive code should avoid text mode.
If You Must Use Text Mode
Sometimes you are writing strings rather than bytes and still want precise newline control. In Python, you can open the file with newline="" or newline="\n" to disable or control translation explicitly.
That keeps Python from replacing newline characters during the write. The file will contain exactly the newline characters present in the string.
Even so, if your source data starts as bytes, binary mode remains the better tool because it avoids both newline translation and character encoding questions.
Other Languages Follow the Same Principle
The rule is not unique to Python. In C, C++, Java, .NET, and many other runtimes, text writers may normalize line endings while binary streams do not. When data integrity matters, use stream APIs that write raw bytes.
A short C example makes the distinction clear:
The "wb" mode is the key detail. It prevents the runtime from translating line endings during output.
Choosing a Normal Form Deliberately
Sometimes the goal is not preserving mixed line endings but normalizing them to a specific convention. In that case, normalize once in memory and then write bytes or write text with a controlled newline policy.
That makes the transformation explicit instead of leaving it to a platform default.
Common Pitfalls
A common mistake is decoding bytes into a string, writing the string in text mode, and expecting the original byte layout to survive. Once you cross into text APIs, encoding and newline translation may change the content.
Another issue is using the wrong file mode on Windows. Code that appears correct on Linux can still produce different files on Windows if it relies on text mode defaults.
Finally, do not confuse editor behavior with runtime behavior. Some editors silently normalize line endings when saving, which can make debugging file output confusing unless you verify the raw bytes.
Summary
- Use binary file modes like
wbwhen exact bytes must be preserved. - Text mode may translate newline characters based on platform rules.
- If you need string I/O with exact newlines, set the newline policy explicitly.
- Normalize line endings yourself when conversion is intentional.
- Verify the written bytes when correctness depends on byte-for-byte fidelity.

