1
00:00:00,000 --> 00:00:03,990
Python makes a distinction between text files and binary files.

2
00:00:04,000 --> 00:00:06,990
Even on operating systems with file systems that don't make that

3
00:00:07,000 --> 00:00:09,990
distinction, Python still does.

4
00:00:10,000 --> 00:00:14,990
So how you read and write binary files, even though it's still very simple, is

5
00:00:15,000 --> 00:00:18,990
different in significant ways from how you read and write text files.

6
00:00:19,000 --> 00:00:26,990
So let's make a working copy of files.py. files-working.py.

7
00:00:27,000 --> 00:00:30,990
Open that working file and we see we have our little loop here that reads

8
00:00:31,000 --> 00:00:34,990
lines of text and prints them to the screen, and let's just go ahead and take

9
00:00:35,000 --> 00:00:44,990
this out and put in olives.jpg and we will save that and run it, and we will

10
00:00:45,000 --> 00:00:50,990
see that we get this UnicodeDecodeError because Python is trying to decode the

11
00:00:51,000 --> 00:00:53,990
text in that JPEG file.

12
00:00:54,000 --> 00:00:54,990
That's a JPEG file.

13
00:00:55,000 --> 00:00:58,990
If we open that up, we will see there is an image of some grapes on a vine

14
00:00:59,000 --> 00:01:01,990
there, and that it not a text file at all.

15
00:01:02,000 --> 00:01:04,990
So what we need to do is we need to open this in binary mode.

16
00:01:05,000 --> 00:01:08,990
So we are going to open it in Read Binary, like that.

17
00:01:09,000 --> 00:01:14,990
And now if we save this and run it, we are going to get this output, which is

18
00:01:15,000 --> 00:01:17,990
still not really what we want.

19
00:01:18,000 --> 00:01:21,990
What's happening is that the Print function is trying to print that in a way

20
00:01:22,000 --> 00:01:24,990
that's text readable, and we are not going to want to write that to a file if we

21
00:01:25,000 --> 00:01:26,990
are making a copy of this.

22
00:01:27,000 --> 00:01:30,990
So what we need to do is we need to open an output file in binary mode and we

23
00:01:31,000 --> 00:01:35,990
need to use our buffered I/O. So we will call this infile, and we will open an

24
00:01:36,000 --> 00:01:41,990
outfile, and call that new.jpg.

25
00:01:42,000 --> 00:01:47,990
Open that in write binary mode, and we are going to do a buffered I/O here.

26
00:01:48,000 --> 00:01:51,990
So we will start by giving ourselves a buffersize.

27
00:01:52,000 --> 00:01:56,990
Let's see, how big is this file?

28
00:01:57,000 --> 00:02:00,990
Properties, it's 142K.

29
00:02:01,000 --> 00:02:04,990
So we will just go ahead and make our buffersize 50000, and that will work fine.

30
00:02:05,000 --> 00:02:12,990
And the rest of it is very similar to how we would do this with the text file,

31
00:02:13,000 --> 00:02:21,990
infile.read(buffersize) and infile.read is not an iterable, so we have to use a

32
00:02:22,000 --> 00:02:31,990
while loop, length of buffer, and we will outfile.write from our buffer.

33
00:02:32,000 --> 00:02:35,990
And we would go ahead and print a dot.

34
00:02:36,000 --> 00:02:43,990
So we see that something is happening on the screen and we will read the next buffer.

35
00:02:44,000 --> 00:02:52,990
When we are all done, we will print a blank line and we will print the word Done.

36
00:02:53,000 --> 00:02:55,990
You can see that we are done.

37
00:02:56,000 --> 00:03:00,990
So what's different here is that by opening the file in binary mode, we are no

38
00:03:01,000 --> 00:03:02,990
longer dealing with text.

39
00:03:03,000 --> 00:03:06,990
The rest of it looks pretty much the same as how we do the buffered reading and

40
00:03:07,000 --> 00:03:09,990
writing with a text file, but the difference here is that we are not working

41
00:03:10,000 --> 00:03:13,990
with text at all. This buffer is now a binary object.

42
00:03:14,000 --> 00:03:15,990
It's not a text object at all.

43
00:03:16,000 --> 00:03:20,990
We will go ahead and we will save this and we will run it and we have got a

44
00:03:21,000 --> 00:03:21,990
few little dots there.

45
00:03:22,000 --> 00:03:27,990
And if we refresh our file system, which Eclipse does not do for us, we have this new.jpg.

46
00:03:28,000 --> 00:03:28,990
I open that up.

47
00:03:29,000 --> 00:03:30,990
There is our JPEG intact.

48
00:03:31,000 --> 00:03:32,990
So we know that copy worked.

49
00:03:33,000 --> 00:03:34,990
I will look at the size of it.

50
00:03:35,000 --> 00:03:38,990
It's the right number of bytes, 142309.

51
00:03:39,000 --> 00:03:41,990
Is that the same as our olives?

52
00:03:42,000 --> 00:03:43,990
It is exactly the same.

53
00:03:44,000 --> 00:03:46,990
So we have an exact duplicate of that file.

54
00:03:47,000 --> 00:03:51,990
So reading and writing binary files, the methodology is very similar, except

55
00:03:52,000 --> 00:03:54,990
you have to use the buffered I/O. You are not going to want to use line

56
00:03:55,000 --> 00:03:57,990
oriented I/O for a binary file.

57
00:03:58,000 --> 00:04:01,990
And most of the time for text files, you are going to use line oriented I/O,

58
00:04:02,000 --> 00:04:03,990
although you can use buffered I/O for text files as well.

59
00:04:04,000 --> 00:04:07,990
As a matter of fact, you can use binary mode for text files if you want to, and

60
00:04:08,000 --> 00:04:10,990
deal with them as bytes, and that will certainly work.

61
00:04:11,000 --> 00:04:14,990
But the distinction here is that with binary files, you have to use the

62
00:04:15,000 --> 00:04:18,990
buffered I/O and you have to use binary data types.

63
00:04:19,000 --> 00:04:23,990
So when you read that file, it's going to read it as an array of bytes and it's

64
00:04:24,000 --> 00:04:25,990
not going to read it as text.

65
00:04:26,000 --> 00:04:29,990
So this is how you do buffered I/O with binary files in Python.

66
00:04:30,000 --> 00:04:32,990
And it's really very simple and it's something that you are going to use now and

67
00:04:33,000 --> 00:04:35,990
then as you are dealing with binary files.

68
00:04:36,000 --> 00:04:40,990
One final note. You will notice that the buffered read method is not an

69
00:04:41,000 --> 00:04:44,990
utterable. If I was going to be doing this a lot, I would go ahead and I would

70
00:04:45,000 --> 00:04:47,990
write a method for an object that is iterable.

71
00:04:48,000 --> 00:04:50,990
That would make this easier for me to do.

72
00:04:51,000 --> 00:04:51,990
It's certainly a matter of style.

73
00:04:52,000 --> 00:04:54,990
It's something that you might think about doing if you are going to be doing

74
00:04:55,000 --> 00:04:58,990
this a lot, and there is an example of how to make a generator function that

75
00:04:59,000 --> 00:05:04,990
generates an iterable in both the Functions chapter and the Classes chapter in this course.

76
00:05:05,000 --> 00:05:15,000
So that's how you do buffered I/O on binary files in Python.

