Skip to main content

Python File I/O: Reading, Writing, and Creating Files

Reading, Writing, and Creating Files in Python

Python provides different built-in functions and methods for working with files. These features, widely known as file I/O (input/output), allows reading and writing data to and from the files located on local computer or network. 

Reading and writing data from and to the files is essential for any  application, as it allows storing  and retrieving data that can be used by the programs/application.

Some of the basic functions are opening and closing files, reading and writing data, and creating the new files. Let's start with opening and closing files before we move on to reading and writing. 

Opening a file

Before we get to reading and writing data from and to the file, we would first have to open a file. 

We can use function 'open()' to open a file. We would need to pass two arguments to this function.
  • Name of the file to be opened.
  • Mode in which we need to open the file. 

Syntax 

file_object = open("sample_file.txt", "r")

This would create a file object which we would be opening through out the program  (until it is closed) to read or write the data. 

There are different modes for opening files which we can use as required in the program. 
  • "r" (read) - Used to open the file for reading. An error would be thrown if the file does not already present. 
  • "w" (write) - Used to open the file for writing. Opening the file with "w" would create a file if not already exist and overwrite the file if already exist. One thing to remember is, this mode should not be used when we want to append the data to the existing file. 
  • "a" (append) - Used to open the file for writing. Opening the file with "a" would create a file if not already exist and data can be appended to the current file if already exist. 
  • "x" (exclusive) - Used to create a new file for writing. An error would be thrown if the file already exist. 
These are the basic modes that allow either one of the two (reading and writing) functions. We could add "+" and "b" to the above modes as required. 
  • Adding "+" would enhance the functionality of the mode. E.g.: mode "r+" would open the file for both read and write where as using the mode "r" would open the file exclusively for reading. 
  • Adding "b" would open the file for reading/writing in binary mode (mostly used for image or audio files). 

Closing a file

We would need to close a file once we are done working with a file to free up the system resources and to make sure the code is clean.

We can use the method 'close()' to close the file. This method needs to be used on the file object opened using the 'open()' function.

Syntax

file_object.close()

Below is an example of opening and closing a file. 

file_object = open("sample_file.txt", "r+")
# read/write data from/to file & any other process required
file_object.close()

There is another way to close a file without explicitly using 'close()'.

This is by using 'open()' function in combination with 'with'. Opening the file in this manner, file object would only be accessible to the block of code under 'with' statement. Once the block is executed, file would be automatically closed and file object cannot be accessed outside the block. 

with open("sample_file.txt", "r+") as f:
    # read/write data from/to file & any other process required

Reading a file

As mentioned in the 'Opening a file' section, file needs to be opened in 'read (r)' mode and create a file object before reading the file. 

Contents of the file can then be read from file object. There are couple of different ways of reading the data from a file. 
  • Reading the full content of a file at once. 
  • Reading one line at a time from a file. 

Reading the full content of a file at once

Using the 'read()' method on the file object, we can read the full content of a file in single statement.

This method returns a string with the content of a file. 

1

2

3

4

5

6

7

8

9

10

# Open a file for reading

file_object = open('sample_file.txt', 'r')

 

# Read the contents of a file at once

contents = file_object.read()

print(contents)

 

# Close the file

file_object.close()

 


In the above example, 'read()' method on 'file_object' returns the full content as a string and is stored in 'content' variable. Below is the output. 

First Line

Second Line

Third Line


Another way to read the full content at once is by using 'readlines()' method on file object. 
Main difference between 'read()' and 'readlines()' is, 
  • read() returns the full content as a string. 
  • readlines() returns the full content as a list with each line as an element in the list. 
Below is the example by using readlines() instead of read().

1

2

3

4

5

6

7

8

9

10

# Open a file for reading

file_object = open('sample_file.txt', 'r')

 

# Reading the contents of a file at once

contents = file_object.readlines()

print(contents)

 

# Close the file

file_object.close()

 


readlines() returns the list with every line as an element. Below is the result.

['First Line\n', 'Second Line\n', 'Third Line']


Reading one line at a time from a file

Using the 'readline()' method on the file object, we can read one line at a time from the file. 

1

2

3

4

5

6

7

8

9

10

# Open a file for reading

file_object = open('sample_file.txt', 'r')


# Reading one line from a file

line = file_object.readline()

print(line)# First Line


# Close the file

file_object.close()



Running 'readline()' method next time would return the next line from the file. 

Another way of reading one line is by looping through the file object. 

1

2

3

4

5

6

7

8

9

10

11

# Open a file for reading

file_object = open('sample_file.txt', 'r')


# Reading one line at a time

# in a loop using file object

for line in file_object:

   print(line)


# Close the file

file_object.close()



One thing to note here is that, file should be present on the system to be able to open the file for reading. If the file not already present, an error 'FileNotFoundError' (No such file or directory) would be thrown. 

So, error handling should be done to capture this error.

Writing (and creating) to a file

File needs to be opened in either 'w', 'a' or 'x' modes to be able to write the content into a file. 

'write()' method on file object can be used to write the content into a file. The way write method works depends on the mode used. 

Using the mode 'w' would open the file for writing, creates the file if not already present and overwrites the content of the file if already present. 

1

2

3

4

5

6

7

8

9

# Open a file for writing

file_object = open('sample_file.txt', 'w')


# Write a line to the file

file_object.write("File is created...")


# Close the file

file_object.close()


In the above example, a new file 'sample_file.txt' is created if not already present and write() method adds a string "File is created...". 

Content of the file would remain same irrespective of the number of times this program is run. As, every time file is opened in 'w' mode file would be cleared followed by adding a line to the file. 

Using the mode 'a' would open the file for writing, creates the file if not already present and appends the data if file already present. 

1

2

3

4

5

6

7

8

9

# Open a file for writing

file_object = open('sample_file.txt', 'a')


# Write a line to the file

file_object.write("File is created...")


# Close the file

file_object.close()


In the above example, a new file 'sample_file.txt" is created if not already present and write() method adds a string "File is created...".

Unlike for the 'w' mode, string "File is created..." is added to the file every time the program is run. If this is program is run for 100 times, this string would be added to the file 100 times. 

Using mode 'x' would create and open the file for writing. If the file already present, program would throw 'FileExistsError' when trying to open with this mode. 

1

2

3

4

5

6

7

8

9

# Open a file for writing

file_object = open('sample_file.txt', 'x')


# Write a line to the file

file_object.write("File is created...")


# Close the file

file_object.close()


In the above example, a new file 'sample_file.txt" is created if not already present and 'FileExistsError' would be thrown if file already exist. 

Unlike for the modes 'w' and 'a', if this program runs for the second time (without removing the file created), program would throw 'FileExistsError'. 

By using the 'write()' we can only write one string at a time. By using 'writelines()' method we can write multiple strings (list of strings) at a time. 

1

2

3

4

5

6

7

8

9

10

11

12

# Open a file for writing

file_object = open('sample_file.txt', 'w')


strings_list = ["First Line\n", "Second Line\n", "Third Line\n"]


# Write a list of strings

file_object.writelines(strings_list)


# Close the file

file_object.close()



In the above example, 'writelines()' writes all the lines in the list passed to the file. This is same as looping over a list and writing one element at a time using 'write()' method. 

Conclusion

Reading and writing from/to a file is an important part of any applications and the use of python's built-in functions makes it easy to create, open a file, read from a file and write to a file. 

I hope this post has provided a good insight on opening a file, reading from a file and writing (and creating) to a file.


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

Comments

Popular posts from this blog

All about READ in RPGLE & Why we use it with SETLL/SETGT?

READ READ is one of the most used Opcodes in RPGLE. As the name suggests main purpose of this Opcode is to read a record from Database file. What are the different READ Opcodes? To list, Below are the five Opcodes.  READ - Read a Record READC - Read Next Changed Record READE - Read Equal Key Record READP - Read Prior Record READPE - Read Prior Equal Record We will see more about each of these later in this article. Before that, We will see a bit about SETLL/SETGT .  SETLL (Set Lower Limit) SETLL accepts Key Fields or Relative Record Number (RRN) as Search Arguments and positions the file at the Corresponding Record (or Next Record if exact match isn't found).  SETGT (Set Greater Than) SETGT accepts Key Fields or Relative Record Number (RRN) as Search Arguments and positions the file at the Next Record (Greater Than the Key value). Syntax: SETLL SEARCH-ARGUMENTS/KEYFIELDS FILENAME SETGT  SEARCH-ARGUMENTS/KEYFIELDS FILENAME One of the below can be passed as Search Arguments. Key Fiel

What we need to know about CHAIN (RPGLE) & How is it different from READ?

CHAIN READ & CHAIN, These are one of the most used (& useful) Opcodes by any RPG developer. These Opcodes are used to read a record from file. So, What's the difference between CHAIN & READ?   CHAIN operation retrieves a record based on the Key specified. It's more like Retrieving Random record from a Database file based on the Key fields.  READ operation reads the record currently pointed to from a Database file. There are multiple Opcodes that start with READ and all are used to read a record but with slight difference. We will see more about different Opcodes and How they are different from each other (and CHAIN) in another article. Few differences to note.  CHAIN requires Key fields to read a record where as READ would read the record currently pointed to (SETLL or SETGT are used to point a Record).  If there are multiple records with the same Key data, CHAIN would return the same record every time. READE can be used to read all the records with the specified Ke

Extract a portion of a Date/Time/Timestamp in RPGLE - IBM i

%SUBDT Extracting Year, Month, Day, Hour, Minutes, Seconds or Milli seconds of a given Date/Time/Timestamp is required most of the times.  This can be extracted easily by using %SUBDT. BIF name looks more similar to %SUBST which is used to extract a portion of string by passing from and two positions of the original string. Instead, We would need to pass a value (i.e., Date, Time or Timestamp ) and Unit (i.e., *YEARS, *MONTHS, *DAYS, *HOURS, *MINUTES, *SECONDS or *MSECONDS) to %SUBDT.  Valid unit should be passed for the type of the value passed. Below are the valid values for each type. Date - *DAYS, *MONTHS, *YEARS Time - *HOURS, *MINUTES, *SECONDS Timestamp - *DAYS, *MONTHS, *YEARS, *HOURS, *MINUTES, *SECONDS, *MSECONDS Syntax: %SUBDT(value : unit { : digits { : decpos} }) Value and Unit are the mandatory arguments.  Digits and Decimal positions are optional and can only be used with *SECONDS for Timestamp. We can either pass the full form for the unit or use the short form. Below i