9

I am writing a python program to copy a file line by line into a new file. The code I have is below in which I am using a loop to copy the file line by line.

However since the number of lines in the file may change, is there a way to copy a file line by line in python without using a loop which relies on numbers, and instead relies on the something like the EOF character to terminate the loop?

import os
import sys

i = 0
f = open("C:\\Users\\jgr208\\Desktop\\research_12\\sap\\beam_springs.$2k","r")
copy = open("C:\\Users\\jgr208\\Desktop\\research_12\\sap\\copy.$2k","wt")
#loop that copies file line by line and terminates loop when i reaches 10
while i < 10:
     line = f.readline()
     copy.write(str(line))
     i = i +1
f.close()
copy.close()
jgr208
  • 2,896
  • 9
  • 36
  • 64
  • 3
    `copy` is a confusing name because Python has a `copy` module. – Steven Rumbalski Jul 20 '12 at 17:46
  • 1
    *"I am writing a python program to copy a file line by line into a new file."* Why? – Marcin Jul 20 '12 at 17:54
  • 2
    Why are you passing line to str() before writing it? It should be coming in as a string, so str() is redundant. – algorowara Jul 20 '12 at 17:55
  • 1
    I said down below, later in the program I will have to change a line in the file so I can not read on the file all at once. Instead I have to duplicate the file line by line. – jgr208 Jul 20 '12 at 18:00

5 Answers5

15

You can iterate over lines in a file object in Python by iterating over the file object itself:

for line in f:
    copy.write(line)

From the docs on file objects:

An alternative approach to reading lines is to loop over the file object. This is memory efficient, fast, and leads to simpler code:

>>> for line in f:
        print line,
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
13

Files can be iterated directly, without the need for an explicit call to readline:

f = open("...", "r")
copy = open("...", "w")
for line in f:
    copy.write(line)
f.close()
copy.close()
chepner
  • 497,756
  • 71
  • 530
  • 681
3

See shutil module for better ways of doing this than copying line-by-line:

shutil.copyfile(src, dst)

Copy the contents (no metadata) of the file named src to a file named dst. dst must be the complete target file name; look at shutil.copy() for a copy that accepts a target directory path. If src and dst are the same files, Error is raised. The destination location must be writable; otherwise, an IOError exception will be raised. If dst already exists, it will be replaced. Special files such as character or block devices and pipes cannot be copied with this function. src and dst are path names given as strings.

Edit: Your question says you are copying line-by-line because the source file is volatile. Something smells wrong about your design. Could you share more details regarding the problem you are solving?

Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119
  • The problem I am solving is making an interface between matlab and sap2000 using python, due to the fact that python can use the matlab and sap2000 COMS. The interface will run a sap2000 analysis and when that is done get the data and do some matrix calculation in matlab. Finally, it will rewrite the file with variables changed on one line based on the matrix calculations, and repeat the process x amount of times. – jgr208 Jul 20 '12 at 18:17
2

Using with statements:

with open("input.txt", "r", encoding="utf-8") as input_file:
  with open("output.txt", "w", encoding="utf-8") as output_file:
    for input_line in input_file:
      output_line = f(input_line) # You can change the line here
      output_file.write(output_line)

Note that input_line contains the end-of-line character(s) (\n or \r\n), if there are any.

kol
  • 27,881
  • 12
  • 83
  • 120
0

Writing line by line can be slow when working with large data. You can accelerate the read/write operations by reading/writing a bunch of lines all at once. Please refer to my answer to a similar question here

computerist
  • 872
  • 8
  • 9