< Return to Video

Python Tutorial: File Objects - Reading and Writing to Files

  • 0:00 - 0:01
    PROFESSOR: Hey there.
  • 0:01 - 0:02
    How's it going, everybody.
  • 0:02 - 0:04
    In this video, we'll
    be learning how
  • 0:04 - 0:05
    to work with file
    objects in Python
  • 0:05 - 0:07
    and some of the
    useful things that we
  • 0:07 - 0:08
    can do with these objects.
  • 0:08 - 0:11
    So whether you use Python for
    desktop or web applications,
  • 0:11 - 0:13
    you're likely going
    to be interacting
  • 0:13 - 0:14
    with files a good bit.
  • 0:14 - 0:16
    So it's definitely
    a good skill to have
  • 0:16 - 0:19
    to know how to properly interact
    with these file objects.
  • 0:19 - 0:20
    OK.
  • 0:20 - 0:21
    So let's go ahead and dive in.
  • 0:21 - 0:25
    So to get a file object, we can
    use the built-in open command.
  • 0:25 - 0:30
    So I have a file here called
    test.txt in the same directory
  • 0:30 - 0:32
    as my Python file.
  • 0:32 - 0:35
    Now if I open this file, we can
    see that it's just a plain text
  • 0:35 - 0:37
    file with multiple lines.
  • 0:37 - 0:39
    So let's see how we
    can open and read
  • 0:39 - 0:41
    this file from within Python.
  • 0:41 - 0:43
    Now the way I'm going to
    open up the file right
  • 0:43 - 0:46
    now isn't the way that
    it's normally recommended.
  • 0:46 - 0:50
    It's usually recommended to use
    a context manager, which I'll
  • 0:50 - 0:51
    show you here in just a second.
  • 0:51 - 0:54
    But to show you why a
    context manager is useful,
  • 0:54 - 0:58
    let me first show you this
    method for opening files first.
  • 0:58 - 0:59
    So what we're
    going to do here is
  • 0:59 - 1:03
    we're going to say f equals
    open and we're just going
  • 1:03 - 1:06
    to open that test.txt file.
  • 1:06 - 1:09
    Now if you're working with files
    from different directories,
  • 1:09 - 1:12
    then you're going to have to
    pass the path to that file
  • 1:12 - 1:13
    into the open command.
  • 1:13 - 1:17
    But since this file is within
    the same directory as my Python
  • 1:17 - 1:20
    file, then I can just pass
    in the name of the file.
  • 1:20 - 1:23
    But if you want to learn
    more about how paths work,
  • 1:23 - 1:26
    then we touch on that a
    little bit in the tutorial I
  • 1:26 - 1:28
    did on the OS module.
  • 1:28 - 1:30
    OK, so the open
    command here allows
  • 1:30 - 1:33
    us to specify whether
    we want to open
  • 1:33 - 1:36
    this file for reading,
    writing, appending,
  • 1:36 - 1:37
    or reading, and writing.
  • 1:37 - 1:39
    And now if we don't
    specify anything,
  • 1:39 - 1:42
    then it defaults to opening
    the file for reading.
  • 1:42 - 1:44
    But I usually like
    to be explicit here.
  • 1:44 - 1:46
    So let's go ahead
    and say that we want
  • 1:46 - 1:48
    to open this file for reading.
  • 1:48 - 1:52
    And we can do this by passing
    in a second argument here.
  • 1:52 - 1:55
    And that's just going to be
    the string of a lowercase r.
  • 1:55 - 1:57
    And we'll touch on
    some of these later.
  • 1:57 - 2:00
    But if I wanted to
    write to a file,
  • 2:00 - 2:03
    then it would just be a
    lowercase w that I'd pass in.
  • 2:03 - 2:06
    Appending to a file
    is a lowercase a.
  • 2:06 - 2:09
    And if I wanted to read
    and write to a file,
  • 2:09 - 2:11
    then I could do an r plus.
  • 2:11 - 2:14
    But for now, we just want to
    read the contents of the file.
  • 2:14 - 2:17
    So let's just pass
    in a lowercase r.
  • 2:17 - 2:20
    So now the file is
    actually open and we
  • 2:20 - 2:21
    can print the name of the file.
  • 2:21 - 2:24
    If I was to do a printf.name.
  • 2:24 - 2:29
    And also before I run this and
    print the name of the file out,
  • 2:29 - 2:31
    there's one more thing
    that we have to do here.
  • 2:31 - 2:35
    If we open a file
    like we just did here,
  • 2:35 - 2:37
    then we need to
    explicitly close the file
  • 2:37 - 2:38
    when we're done using it.
  • 2:38 - 2:43
    And to do this, I'm going
    to do it by saying f.close.
  • 2:43 - 2:45
    So now that we've closed
    that file, let's go ahead
  • 2:45 - 2:46
    and run this.
  • 2:46 - 2:49
    And you can see that it printed
    out the name of the file
  • 2:49 - 2:50
    that we opened.
  • 2:50 - 2:52
    And so this has some
    more information
  • 2:52 - 2:53
    that we can print out.
  • 2:53 - 2:56
    Also, if we wanted to print the
    mode that the file is currently
  • 2:56 - 2:59
    opened with, I can do a f.mode.
  • 2:59 - 3:01
    And if I run that, you
    can see it prints out
  • 3:01 - 3:05
    a lowercase r because we
    open the file for reading.
  • 3:05 - 3:08
    So now even though that this
    works the way that we've just
  • 3:08 - 3:10
    now done this, let me show
    you how to instead open
  • 3:10 - 3:15
    the file using a context manager
    and why, for most use cases,
  • 3:15 - 3:17
    you'll want to work
    with files this way.
  • 3:17 - 3:20
    So if we open the
    file like we did here,
  • 3:20 - 3:24
    then we have to remember to
    explicitly close the file.
  • 3:24 - 3:26
    If we don't close
    the file, then you
  • 3:26 - 3:28
    can end up with
    leaks that cause you
  • 3:28 - 3:32
    to run over the maximum allowed
    file descriptors on your system
  • 3:32 - 3:34
    and your applications
    could throw an error.
  • 3:34 - 3:36
    So it's always important
    to make sure that you
  • 3:36 - 3:38
    close the files that you open.
  • 3:38 - 3:41
    So in order to use
    a context manager,
  • 3:41 - 3:43
    then it's kind of similar.
  • 3:43 - 3:46
    But we can do this
    using the with keyword.
  • 3:46 - 3:50
    So we can say with and then I'm
    just going to copy all of this.
  • 3:50 - 3:54
    So with open test.txt
    in read mode.
  • 3:54 - 3:57
    And then here at the end,
    I'm going to say as f,
  • 3:57 - 4:01
    and then I'm going to put in
    a opening for our block here.
  • 4:01 - 4:03
    Now, this can be a little
    confusing to people at first,
  • 4:03 - 4:07
    because the variable name is
    actually over here on the right
  • 4:07 - 4:10
    using as f instead
    of over on the left
  • 4:10 - 4:12
    when we said f equals open.
  • 4:12 - 4:15
    But the benefit of
    these context managers
  • 4:15 - 4:17
    is that they allow
    us to work with files
  • 4:17 - 4:18
    from within this block.
  • 4:18 - 4:20
    And after we exit
    that block of code,
  • 4:20 - 4:23
    it'll automatically
    close the file for us.
  • 4:23 - 4:25
    So we don't have to worry
    about whether or not
  • 4:25 - 4:27
    we add in these closes here.
  • 4:27 - 4:29
    Now this will also
    close the file
  • 4:29 - 4:31
    if there are any
    exceptions that are thrown
  • 4:31 - 4:33
    or anything like that.
  • 4:33 - 4:35
    So that's why using
    these context managers
  • 4:35 - 4:37
    are considered a best practice.
  • 4:37 - 4:40
    And it just automatically takes
    care of all that cleanup for us.
  • 4:40 - 4:45
    So now I'm going to go ahead and
    delete my outside open and close
  • 4:45 - 4:46
    statements there.
  • 4:46 - 4:48
    Now one thing that some
    people don't realize
  • 4:48 - 4:52
    is that you actually have
    access to this f variable.
  • 4:52 - 4:54
    For now, I'm just
    going to say pass
  • 4:54 - 4:56
    within this context manager.
  • 4:56 - 4:59
    Now we actually have access
    to this file object variable
  • 4:59 - 5:02
    after we exit the
    context manager.
  • 5:02 - 5:03
    But the file will
    just be closed.
  • 5:03 - 5:08
    So for example, if I print
    the closed method on f now
  • 5:08 - 5:12
    and run that, you can
    see that it returns true.
  • 5:12 - 5:15
    But even though that we have
    access to this variable here,
  • 5:15 - 5:16
    it is closed.
  • 5:16 - 5:18
    So it's not like we
    can read from it.
  • 5:18 - 5:21
    If I try to read the
    contents from the file
  • 5:21 - 5:23
    and print that out,
    then you can see
  • 5:23 - 5:25
    that it throws a
    value error here
  • 5:25 - 5:29
    and it says I/O operation
    on a closed file.
  • 5:29 - 5:32
    So for what we want, we're going
    to have to work with this file
  • 5:32 - 5:35
    from within this
    context manager.
  • 5:35 - 5:37
    And for the rest
    of the video, I'll
  • 5:37 - 5:39
    be using these context
    managers to work with files
  • 5:39 - 5:40
    since it's a good practice.
  • 5:40 - 5:42
    But I wanted to show you
    the other way first in case
  • 5:42 - 5:45
    you see it in
    examples or wondered
  • 5:45 - 5:46
    why I wasn't doing it that way.
  • 5:46 - 5:48
    OK, so back to our file.
  • 5:48 - 5:51
    So we just tried to read the
    contents from the closed file
  • 5:51 - 5:53
    and got our error.
  • 5:53 - 5:54
    But let's look at
    how we can read
  • 5:54 - 5:58
    the contents from the file from
    here within our context manager.
  • 5:58 - 6:02
    So let's create a variable
    called f_contents.
  • 6:02 - 6:05
    And this will just hold
    the contents of our file.
  • 6:05 - 6:11
    Now if we do an f.read
    and if I print this out,
  • 6:11 - 6:16
    and actually I need to actually
    print out that f_contents.
  • 6:16 - 6:18
    So if I save that
    and print that out,
  • 6:18 - 6:20
    then you can see that
    it printed out all
  • 6:20 - 6:22
    of the contents of our file.
  • 6:22 - 6:24
    Now if you have a
    small file, then this
  • 6:24 - 6:26
    is probably what you want.
  • 6:26 - 6:29
    But what if we have an extremely
    large file that we want to read,
  • 6:29 - 6:32
    but we don't want to load all
    of the contents of that file
  • 6:32 - 6:33
    into memory.
  • 6:33 - 6:35
    Well, there are a
    couple of other methods
  • 6:35 - 6:38
    here that we have available for
    reading file contents instead
  • 6:38 - 6:39
    of f.read.
  • 6:39 - 6:45
    So just to look at a couple of
    those, I could say f.readlines.
  • 6:45 - 6:47
    And if I print
    this out, then you
  • 6:47 - 6:51
    can see that we get a list of
    all of the lines in the file.
  • 6:51 - 6:53
    And it looks a little weird
    because we have our new line
  • 6:53 - 6:54
    characters in there.
  • 6:54 - 6:56
    But if we look
    through this list,
  • 6:56 - 6:59
    then it actually gets
    every line of the file
  • 6:59 - 7:02
    as a different
    element of that list.
  • 7:02 - 7:07
    Now instead of f.readlines,
    I could do f.readline.
  • 7:07 - 7:09
    And if I save that
    and run it, then you
  • 7:09 - 7:13
    can see that read line grabbed
    the first line of our file.
  • 7:13 - 7:16
    Now every time that
    we run f.readline,
  • 7:16 - 7:19
    it gets the next
    line in our file.
  • 7:19 - 7:22
    So if I was to copy
    all of this and then
  • 7:22 - 7:25
    do it again and
    run that, now you
  • 7:25 - 7:27
    can see that it got the
    first and the second lines
  • 7:27 - 7:28
    from the file.
  • 7:28 - 7:30
    Now this printed out
    a little weird here
  • 7:30 - 7:34
    because the print statement
    ends with a new line by default.
  • 7:34 - 7:38
    But if I go up here and
    pass in an empty string
  • 7:38 - 7:40
    to the end of our
    print statement,
  • 7:40 - 7:45
    then it will no longer add
    in that extra new line.
  • 7:45 - 7:47
    And now you can see that
    those are the way that they
  • 7:47 - 7:49
    are in the file.
  • 7:49 - 7:50
    But we still haven't
    solved our problem
  • 7:50 - 7:53
    of how we can read
    all of the content
  • 7:53 - 7:55
    from an extremely large file.
  • 7:55 - 7:57
    If we read the entire
    file in all at once,
  • 7:57 - 7:59
    then we could run out of memory.
  • 7:59 - 8:01
    And we don't want
    to go through and do
  • 8:01 - 8:04
    F line thousands of times.
  • 8:04 - 8:06
    So what we're going
    to do here is,
  • 8:06 - 8:09
    instead of using read
    line or read lines,
  • 8:09 - 8:15
    we can simply iterate over the
    lines in a file by saying for--
  • 8:15 - 8:20
    let me go to a new line
    here, for line in f,
  • 8:20 - 8:23
    and then from here, we
    can just print that line.
  • 8:23 - 8:27
    So I'm going to copy
    that and save that.
  • 8:27 - 8:29
    So now let me go ahead and
    comment out these lines
  • 8:29 - 8:32
    and run this iteration
    over the lines.
  • 8:32 - 8:35
    And you can see that it
    printed out all of the lines
  • 8:35 - 8:36
    in our file.
  • 8:36 - 8:38
    Now this is efficient
    because it's not
  • 8:38 - 8:41
    reading in all of the contents
    from our file all at once.
  • 8:41 - 8:44
    So it's not a memory issue
    that we have to worry about.
  • 8:44 - 8:46
    What it's going
    to do is it's just
  • 8:46 - 8:50
    going to go through and get one
    line at a time from the file.
  • 8:50 - 8:52
    Now, this is usually good
    enough for most people,
  • 8:52 - 8:56
    but sometimes you may want more
    control over exactly what you're
  • 8:56 - 8:57
    reading from the file.
  • 8:57 - 9:01
    Now, if we go back, I'm going to
    go ahead and delete this line.
  • 9:01 - 9:05
    If we go back to our f.readline
    here and I'm going to get
  • 9:05 - 9:09
    rid of that one.
  • 9:09 - 9:12
    Now I'm going to go
    back to using f.read.
  • 9:12 - 9:15
    And if you remember, this
    read in the entire contents
  • 9:15 - 9:16
    of the file.
  • 9:16 - 9:18
    So if I run that,
    you can see that we
  • 9:18 - 9:19
    got the exact same thing.
  • 9:19 - 9:23
    But with f.read, we can actually
    specify the amount of data
  • 9:23 - 9:25
    that we want to read
    at a time by passing
  • 9:25 - 9:27
    in the size as an argument.
  • 9:27 - 9:31
    So if I pass in a 100
    to our read method
  • 9:31 - 9:34
    and then print this
    out, you can see
  • 9:34 - 9:38
    that it printed out the first
    100 characters of our file
  • 9:38 - 9:40
    instead of printing the
    whole thing all at once.
  • 9:40 - 9:46
    Now, if I was to copy
    this and run this again,
  • 9:46 - 9:50
    then you can see that it
    printed out the rest of the file
  • 9:50 - 9:52
    because it picked
    up where it left off
  • 9:52 - 9:54
    and read 100 more
    characters of the file.
  • 9:54 - 9:57
    Now, when we reach
    the end of the file,
  • 9:57 - 9:59
    then read will just
    return an empty string.
  • 9:59 - 10:04
    So if I was to copy this for
    a third time and rerun this,
  • 10:04 - 10:06
    then you can see
    that nothing happens.
  • 10:06 - 10:09
    Because what happens when we
    reach the end of the file,
  • 10:09 - 10:11
    read just returns
    an empty string.
  • 10:11 - 10:15
    So this print statement is just
    printing out an empty string.
  • 10:15 - 10:18
    So how are we going to use
    this technique in order
  • 10:18 - 10:21
    to read in a large file?
  • 10:21 - 10:25
    So since we don't know exactly
    how long the file will be,
  • 10:25 - 10:27
    we're going to have to use some
    kind of loop that just iterates
  • 10:27 - 10:30
    over small chunks at a time.
  • 10:30 - 10:33
    So instead of hard
    coding in 100 here,
  • 10:33 - 10:38
    I'm going to create a variable
    here called size_to_read.
  • 10:38 - 10:42
    And for now, we'll just go
    ahead and set that equal to 100.
  • 10:42 - 10:46
    So now instead of passing
    in 100 to f.read, let's
  • 10:46 - 10:48
    just pass in this size_to_read.
  • 10:48 - 10:53
    OK, so this will grab the first
    100 characters of our file.
  • 10:53 - 10:56
    Now remember when we hit the
    end of the file, then read
  • 10:56 - 10:58
    will just return
    an empty string.
  • 10:58 - 11:06
    So if we do a while loop and say
    while the length of f_contents
  • 11:06 - 11:12
    is greater than 0, then we
    will print out the contents
  • 11:12 - 11:14
    that we got from read.
  • 11:14 - 11:16
    Now don't run it like
    this yet, because this
  • 11:16 - 11:19
    will be an infinite
    loop whenever advancing
  • 11:19 - 11:20
    the contents of the file.
  • 11:20 - 11:22
    After it prints the
    contents, then we
  • 11:22 - 11:25
    want to read in the next
    chunk of characters.
  • 11:25 - 11:28
    So in order to do that,
    then we just have to,
  • 11:28 - 11:35
    again, say f_contents equals
    f.read of that sized chunk.
  • 11:35 - 11:37
    Now, what it's going
    to do after this line
  • 11:37 - 11:41
    here is that it's going to kick
    us back out to the while loop,
  • 11:41 - 11:45
    and it will check if we've
    hit the end of the file,
  • 11:45 - 11:49
    because f.read will
    return an empty string
  • 11:49 - 11:51
    and it won't meet
    this condition.
  • 11:51 - 11:53
    So now if I go
    ahead and run this,
  • 11:53 - 11:55
    then you can see that
    it printed out all
  • 11:55 - 11:57
    of the contents of our file.
  • 11:57 - 11:59
    So to get a better idea
    of what's going on here,
  • 11:59 - 12:03
    let's change the size to
    read to 10 characters instead
  • 12:03 - 12:04
    of 100 characters.
  • 12:04 - 12:09
    And every time that we print
    out f.contents here, instead
  • 12:09 - 12:13
    of an empty string, let's
    make this an asterisk.
  • 12:13 - 12:15
    So now if I print
    this out, then you
  • 12:15 - 12:17
    can see it's a little
    more clear that we're
  • 12:17 - 12:20
    looping through 10
    characters at a time,
  • 12:20 - 12:23
    and it's printing out these
    asterisks through every loop.
  • 12:23 - 12:25
    So you can see that it
    came through the loop here
  • 12:25 - 12:27
    and it printed out these.
  • 12:27 - 12:30
    And then the asterisk that we
    know that it's just that chunk.
  • 12:30 - 12:33
    Then it printed out the
    next 10 characters and then
  • 12:33 - 12:34
    the next 10 characters
    and so on until we
  • 12:34 - 12:36
    got to the end of the file.
  • 12:36 - 12:38
    Now when we read
    from files, you can
  • 12:38 - 12:40
    see that it advances
    its position every time.
  • 12:40 - 12:45
    So we can actually see the
    current position using f.tell.
  • 12:45 - 12:49
    So what I'm going to do is I'm
    going to comment out this while
  • 12:49 - 12:50
    loop here.
  • 12:50 - 12:53
    And down here, I'm
    going to say print
  • 12:53 - 12:55
    and we'll print out f.tell.
  • 12:55 - 12:57
  • 12:57 - 12:59
    So if I go ahead
    and run that, you
  • 12:59 - 13:02
    can see the f.tell returned 10.
  • 13:02 - 13:05
    So it's saying that we're
    currently at the 10th position
  • 13:05 - 13:06
    in the file.
  • 13:06 - 13:10
    And that's because we've already
    read in 10 characters here.
  • 13:10 - 13:13
    And we can manipulate
    our current position
  • 13:13 - 13:15
    using the seek method.
  • 13:15 - 13:17
    So to show an
    example of this, let
  • 13:17 - 13:21
    me print the first 20
    characters of the file
  • 13:21 - 13:24
    by running f.read twice.
  • 13:24 - 13:26
    So I'm going to go
    ahead and print out
  • 13:26 - 13:30
    the contents after the
    first 10 characters there.
  • 13:30 - 13:33
    And then I'm going to
    do this a second time
  • 13:33 - 13:35
    to get the next 10 characters.
  • 13:35 - 13:37
    And I'm going to go
    ahead and take out
  • 13:37 - 13:41
    this second empty
    string there so that it
  • 13:41 - 13:43
    pushes our finished
    statement out of the way.
  • 13:43 - 13:46
    So now actually let
    me get rid of f.tell
  • 13:46 - 13:49
    here and go ahead and run this.
  • 13:49 - 13:52
    So we can see that it
    printed out the first 20
  • 13:52 - 13:54
    characters of our file.
  • 13:54 - 13:57
    Now when we read in
    this second chunk here,
  • 13:57 - 14:01
    it picked up at the 10th
    position and read in the next 10
  • 14:01 - 14:03
    characters like we would expect.
  • 14:03 - 14:08
    But what if I wanted that second
    read to instead start back
  • 14:08 - 14:10
    at the beginning of the file?
  • 14:10 - 14:13
    And we can do this with f.seek.
  • 14:13 - 14:20
    So between these two reads,
    if I was to do an f.seek of 0
  • 14:20 - 14:23
    and save that and
    ran it, now you
  • 14:23 - 14:26
    can see that it's
    set our position back
  • 14:26 - 14:28
    to the beginning of the file.
  • 14:28 - 14:31
    So the second time we
    read in our contents,
  • 14:31 - 14:34
    it starts back at the beginning
    instead of picking up where we
  • 14:34 - 14:36
    left off after the first read.
  • 14:36 - 14:41
    Now we used seek 0 to start
    at the beginning of the file,
  • 14:41 - 14:44
    but you can use it to change
    the position to any location
  • 14:44 - 14:45
    that you'd like.
  • 14:45 - 14:47
    So now let's take a look
    at writing to files.
  • 14:47 - 14:50
    And a lot of this will
    be similar to reading.
  • 14:50 - 14:52
    So first of all,
    what happens if we
  • 14:52 - 14:57
    try to write from
    within a file that we
  • 14:57 - 14:59
    have opened in read mode?
  • 14:59 - 15:01
    So let's go ahead and try that.
  • 15:01 - 15:05
    So I'll do an f.write and I'll
    just do an f.write of test.
  • 15:05 - 15:08
    And I'm going to go ahead and
    get rid of that while loop
  • 15:08 - 15:10
    also and save that.
  • 15:10 - 15:13
    So you see when I have
    a file open in read mode
  • 15:13 - 15:15
    and try to write that
    we get an error that
  • 15:15 - 15:18
    says that this is not writable.
  • 15:18 - 15:21
    So we have to have the
    file open in write mode.
  • 15:21 - 15:24
    So now back up here
    within our open statement,
  • 15:24 - 15:29
    let's create a new
    file called test2.txt.
  • 15:29 - 15:33
    And instead of reading, we
    are going to write to it.
  • 15:33 - 15:37
    Now in order to do that, we can
    just say a lowercase w instead
  • 15:37 - 15:39
    of that lowercase r.
  • 15:39 - 15:41
    Now you can see over
    here in our directory
  • 15:41 - 15:43
    that we don't have
    a test2.txt yet.
  • 15:43 - 15:46
    Now, if the file
    doesn't exist already,
  • 15:46 - 15:48
    then this will go
    ahead and create it.
  • 15:48 - 15:52
    Now, if the file does exist,
    then it will overwrite it.
  • 15:52 - 15:55
    So be careful if you're writing
    to a file that already exists.
  • 15:55 - 15:57
    Now if you don't want
    to overwrite a file,
  • 15:57 - 16:01
    then you can use a lowercase
    a for appending to the file.
  • 16:01 - 16:03
    But we're going to go
    ahead and overwrite
  • 16:03 - 16:04
    this file if it exists.
  • 16:04 - 16:08
    So first of all, instead of
    writing to this file, I'm just
  • 16:08 - 16:10
    going to go ahead and put
    in a pass statement here,
  • 16:10 - 16:13
    which basically says
    don't do anything.
  • 16:13 - 16:15
    So I'm going to go
    ahead and run this.
  • 16:15 - 16:19
    And you can see that
    it created test2.txt.
  • 16:19 - 16:22
    So I didn't actually have to
    write anything to the file
  • 16:22 - 16:24
    in order to create it.
  • 16:24 - 16:28
    Just using the open with the
    write mode will create the file.
  • 16:28 - 16:32
    So now in order to
    write to this file, then
  • 16:32 - 16:34
    we can just do
    what we did before.
  • 16:34 - 16:37
    We can do an f.write test.txt.
  • 16:37 - 16:39
    So I'm going to go
    ahead and run that.
  • 16:39 - 16:42
    Now if we go over
    here to test2.txt,
  • 16:42 - 16:45
    then you can see that it
    wrote test to our file.
  • 16:45 - 16:49
    Now if I go back here and do
    another write to this file,
  • 16:49 - 16:52
    then it's going to pick
    up where we left off,
  • 16:52 - 16:55
    just like the read method did.
  • 16:55 - 16:58
    So now if I run this
    and go back to the file,
  • 16:58 - 17:02
    then you can see that it
    wrote test twice back to back.
  • 17:02 - 17:05
    Now you can actually use
    seek when writing files also
  • 17:05 - 17:08
    to set the position back to
    the beginning of the file.
  • 17:08 - 17:10
    And we can do this.
  • 17:10 - 17:13
    If I go back here between
    these two write statements
  • 17:13 - 17:16
    and I was to do an f.seek of 0.
  • 17:16 - 17:21
    Now if I run this, then you
    can see that the second test
  • 17:21 - 17:22
    overwrote the first one.
  • 17:22 - 17:24
    So seek can get a
    little confusing
  • 17:24 - 17:29
    for file writes because it
    doesn't overwrite everything,
  • 17:29 - 17:30
    only what it needs to overwrite.
  • 17:30 - 17:34
    So for example, if instead of
    writing the same thing twice,
  • 17:34 - 17:38
    if I was to do an
    f.seek at the beginning
  • 17:38 - 17:41
    and write out an r as
    my second one there.
  • 17:41 - 17:44
    And now if I run that
    and go back to the file,
  • 17:44 - 17:48
    then you can see that the r
    only overwrote the t in test.
  • 17:48 - 17:51
    It didn't delete the
    rest of the content.
  • 17:51 - 17:55
    So using file seek whenever
    I'm writing to files,
  • 17:55 - 17:56
    it can get a little confusing.
  • 17:56 - 17:58
    And I don't use it a whole lot.
  • 17:58 - 18:00
    But maybe there are
    some use cases out there
  • 18:00 - 18:03
    that you guys will
    find it useful for.
  • 18:03 - 18:05
    OK, so let's go ahead
    and pull all of this
  • 18:05 - 18:09
    together and use read and
    write on multiple files
  • 18:09 - 18:10
    at the same time.
  • 18:10 - 18:12
    So we're going to
    use this to make
  • 18:12 - 18:15
    a copy of our test.txt file.
  • 18:15 - 18:19
    So let's go ahead and delete
    our test2.txt file here.
  • 18:19 - 18:21
    So that we don't
    confuse the two.
  • 18:21 - 18:24
    And I'm going to go ahead
    and close that there.
  • 18:24 - 18:28
    So I'm going to go ahead
    and get rid of these here.
  • 18:28 - 18:34
    So first let's open our original
    test.txt file in a read mode.
  • 18:34 - 18:38
    And instead of f here,
    I'm going to use rf.
  • 18:38 - 18:41
    And I'll just say rf
    there for read file,
  • 18:41 - 18:43
    since this is the
    file that we're
  • 18:43 - 18:46
    going to read from in
    order to write to our copy.
  • 18:46 - 18:50
    So now within this
    with statement here,
  • 18:50 - 18:54
    I'm going to go ahead and let's
    go ahead and copy all of this
  • 18:54 - 18:58
    and paste another
    open within here.
  • 18:58 - 19:03
    And I'm going to call this a
    test_copy.txt and I'm going
  • 19:03 - 19:05
    to open this in write mode.
  • 19:05 - 19:09
    And I'm going to call
    this wf for write file.
  • 19:09 - 19:11
    Now you can actually put
    both of these open statements
  • 19:11 - 19:14
    on a single line
    separated by a comma.
  • 19:14 - 19:17
    But I think readability
    here is pretty important.
  • 19:17 - 19:19
    And mixing those two on
    one line is sometimes
  • 19:19 - 19:21
    difficult to understand,
    at least for me.
  • 19:21 - 19:24
    So this is usually how I work
    with multiple files at a time
  • 19:24 - 19:28
    is putting them on two
    different lines, one
  • 19:28 - 19:30
    nested within the other.
  • 19:30 - 19:33
    So now within here, we
    have two files open--
  • 19:33 - 19:38
    rf for reading our original file
    and wf for writing to our copy.
  • 19:38 - 19:46
    Now, to do this, it's just as
    easy as saying for line in rf,
  • 19:46 - 19:53
    we want to do a
    wf.write of that line.
  • 19:53 - 19:55
    So now let's walk over
    this one more time.
  • 19:55 - 19:58
    So we have our original
    file opened and we're
  • 19:58 - 20:00
    reading from that file.
  • 20:00 - 20:03
    And we have a file that doesn't
    exist yet that's our copy.
  • 20:03 - 20:05
    And we're writing to that file.
  • 20:05 - 20:10
    And we're saying for each
    line in our original file,
  • 20:10 - 20:15
    write that line to wf, which is
    the file that we are copying to.
  • 20:15 - 20:19
    So if I go ahead and run that,
    then you can see that it created
  • 20:19 - 20:21
    this test_copy.txt file.
  • 20:21 - 20:24
    And if I open this,
    you can see that it is
  • 20:24 - 20:25
    an exact copy of our original.
  • 20:25 - 20:29
    And lastly, let's look at how
    we can do something similar
  • 20:29 - 20:31
    and copy a large picture file.
  • 20:31 - 20:34
    Now this is going to
    be slightly different.
  • 20:34 - 20:36
    So if I look in my
    current directory that
  • 20:36 - 20:39
    has my Python script that
    I'm currently running,
  • 20:39 - 20:42
    I also have a picture of my
    dog here when he was a puppy.
  • 20:42 - 20:46
    And let's go ahead and try
    to copy this picture file
  • 20:46 - 20:48
    using file objects in Python.
  • 20:48 - 20:51
    Now this file here
    is called bronx.jpeg.
  • 20:51 - 20:57
    And if I just try to replace our
    text files with these picture
  • 20:57 - 21:04
    files, and down here, I'll
    call this bronx_copy.jpeg.
  • 21:04 - 21:07
    Now, this is exactly the
    same as our previous example,
  • 21:07 - 21:10
    but we're trying to use a
    picture instead of a text file.
  • 21:10 - 21:13
    Now if I try to
    run this, you can
  • 21:13 - 21:18
    see that we got an error down
    here that says utf codec can't
  • 21:18 - 21:21
    decode byte in position 0.
  • 21:21 - 21:23
    So in order to work
    with images, we're
  • 21:23 - 21:25
    going to have to open
    these files in binary mode.
  • 21:25 - 21:27
    And all that means
    is that we're going
  • 21:27 - 21:31
    to be reading and writing bytes
    instead of working with text.
  • 21:31 - 21:33
    Now I'm not going to
    go into the specifics,
  • 21:33 - 21:36
    but if anyone is curious
    about the differences,
  • 21:36 - 21:38
    then I'll try to leave some
    resources in the description
  • 21:38 - 21:41
    section as to what
    exactly that means.
  • 21:41 - 21:43
    But for this case, in order
    to work with these pictures,
  • 21:43 - 21:51
    to use binary mode, we can just
    append a B to our read r here
  • 21:51 - 21:53
    and our write w there.
  • 21:53 - 21:55
    So now with that
    one simple change
  • 21:55 - 21:58
    if I save that and
    now run it, then you
  • 21:58 - 22:02
    can see that we do have this
    copied picture file here.
  • 22:02 - 22:04
    And if I go over
    to finder, then you
  • 22:04 - 22:08
    can see that, that
    file copied exactly
  • 22:08 - 22:10
    the way that the original is.
  • 22:10 - 22:12
    So last thing here.
  • 22:12 - 22:14
    Now I said earlier
    that sometimes you
  • 22:14 - 22:17
    want more control over exactly
    what you're reading and writing.
  • 22:17 - 22:20
    So instead of doing
    this line by line,
  • 22:20 - 22:25
    let's instead do this
    in specific chunk sizes.
  • 22:25 - 22:27
    And we saw something
    like this earlier
  • 22:27 - 22:29
    when we were learning
    how to read our files.
  • 22:29 - 22:35
    So to do this, let's just do a
    chunk size and we'll set this
  • 22:35 - 22:38
    equal to 4,096.
  • 22:38 - 22:39
    Now you can choose
    different sizes,
  • 22:39 - 22:41
    but this is the one
    that I'm choosing here.
  • 22:41 - 22:45
    So now let's do an rf_chunk.
  • 22:45 - 22:50
    And we're just going to read in
    a chunk of our read file here.
  • 22:50 - 22:56
    So I'll say rf.read and I'll
    pass in this chunk size.
  • 22:56 - 22:59
    So now we're reading that much
    data from our original picture.
  • 22:59 - 23:03
    So now let's create a loop
    that will write these chunks
  • 23:03 - 23:05
    to our copy until
    there's nothing left
  • 23:05 - 23:07
    to read from the original.
  • 23:07 - 23:09
    And if you remember
    from earlier to do this,
  • 23:09 - 23:12
    we can do a while loop.
  • 23:12 - 23:19
    And while the length of this
    chunk here is greater than 0,
  • 23:19 - 23:24
    then we want to take our copy
    file and write that chunk to it.
  • 23:24 - 23:27
    So I'm going to write
    this chunk to our copy.
  • 23:27 - 23:30
    And then to keep this from
    being an infinite loop,
  • 23:30 - 23:33
    I have to read in
    the next chunk size.
  • 23:33 - 23:37
    So I'll paste that in there
    to read in the next chunk
  • 23:37 - 23:39
    from the original file.
  • 23:39 - 23:42
    So now if I come up
    here and I delete
  • 23:42 - 23:44
    this copy that we just created.
  • 23:44 - 23:46
    So I'm going to delete that.
  • 23:46 - 23:49
    And now I'm going to go
    ahead and rerun it using
  • 23:49 - 23:50
    the code that we just wrote.
  • 23:50 - 23:53
    And you can see that it
    made that copy there.
  • 23:53 - 23:56
    And if I go back over to
    finder and open up that copy,
  • 23:56 - 23:59
    then you can see that it made
    an exact copy of our original.
  • 23:59 - 24:02
    So I think that's going
    to do it for this video.
  • 24:02 - 24:04
    There's a lot more that we
    could look at with files,
  • 24:04 - 24:06
    and I'll plan on
    putting together
  • 24:06 - 24:08
    some tutorials in
    the near future
  • 24:08 - 24:11
    for how to work with temporary
    files, in-memory files
  • 24:11 - 24:12
    and things like that.
  • 24:12 - 24:14
    But I hope that this
    was a good introduction
  • 24:14 - 24:16
    into working with files and
    some of the useful things
  • 24:16 - 24:17
    that we can do with them.
  • 24:17 - 24:19
    Now, if you have
    any questions, then
  • 24:19 - 24:21
    feel free to ask in the
    comment section below
  • 24:21 - 24:22
    and I'll do my best
    to answer those.
  • 24:22 - 24:24
    Be sure to subscribe
    for future videos.
  • 24:24 - 24:26
    And Thank you all for watching.
  • 24:26 - 24:33
Title:
Python Tutorial: File Objects - Reading and Writing to Files
Description:

more » « less
Video Language:
English
Duration:
24:33

English subtitles

Revisions