# Handling multiple files at the same time

**URL:** https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037
**Category:** Performance
**Tags:** question, strings, file
**Created:** [April 26, 2022, 9:12am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037 "2022-04-26T09:12:19Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Drachta](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@Drachta](https://discourse.julialang.org/u/Drachta)
#### Post date: [April 26, 2022, 9:12am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/1 "2022-04-26T09:12:20Z")

</div>

Hello,

I wish to replace some occurrence in a file and save it under a new file. The following does what I need, but it reads the entire file before making the substitution.  
Is there a better way to do this ?

```julia
some_variable = "Oranges"

open("some_file", "r") do file
    global data = read(file, String)
end

data = replace(data, r"some text (?i)" => "$some_variable")

open("another_file", "w") do io
    println(io, data)
end

```

I’m using Julia 1.6.5 under Windows 7.

Thanks!

---

<div class="post-metadata">

### Author: ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)
#### Post date: [April 26, 2022, 9:17am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/2 "2022-04-26T09:17:23Z")

</div>

I think you should be able to nest `open` calls.

```julia
open("in.txt","r") do io_in
  open("out.txt","r") do io_out
   readline(io_in) |> print
   readline(io_out) |> print
  end
end

```

you can also use open without a `do` block.

```julia
io_in = open("in.txt","r")
io_out = open("in.txt","w")
# do stuff
close(io_in)
close(io_out)

```

The implementation when using a function as a first argument or a `do` block looks like this:

```julia
function open(f::Function, args...; kwargs...)
    io = open(args...; kwargs...)
    try
        f(io)
    finally
        close(io)
    end
end

```

However, I am not sure if there is an implementation of `replace` that acts on data streams.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [April 26, 2022, 9:39am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/3 "2022-04-26T09:39:31Z")

</div>

Assuming that you can do your replacements on a line by line basis, something like this should work:

```julia
open("another_file", "w") do out
    for line in eachline("some_file")
        println(out, replace(line, r"some text (?i)" => "$some_variable"))
    end
end

```

If you have very large files it’s probably better to read larger blocks than a line at a time, but you need to arrange it so the things you replace are not split between blocks.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [April 26, 2022, 9:49am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/4 "2022-04-26T09:49:39Z")

</div>

Possibly of help, this is some production code of mine which solves the easier task of determining whether two files are identical.

```julia
block_size = 2 ^ 20
open(file.reference, "r") do reference
    open(file.filename, "r") do file
        while true
            reference_block = read(reference, block_size)
            file_block = read(file, block_size)
            reference_block == file_block || return false
            length(reference_block) < block_size && return true
        end
    end
end

```

---

<div class="post-metadata">

### Author: ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)
#### Post date: [April 26, 2022, 9:53am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/5 "2022-04-26T09:53:30Z")

</div>

I also found [BufferedStreams.jl](https://juliahub.com/ui/Packages/BufferedStreams/wMWKi/1.0.0). This might implement some useful functionality such as anchoring a stream.

Also if the content you want to replace starts with a constant sequence `readuntil` might be useful.

---

<div class="post-metadata">

### Author: ![Drachta](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@Drachta](https://discourse.julialang.org/u/Drachta)
#### Post date: [April 26, 2022, 10:43am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/6 "2022-04-26T10:43:40Z")

</div>

Thank you all for your answers !

So, if I need a a line by line replacement, something like this would be good?

```julia
some_variable = "Oranges"

open("some_output_file", "w") do file_out
open("some_intput_file", "r") do file_in
    while !eof(file_in)
        readline(file_in) |> data -> replace(data, r"some text (?i)" => "$some_variable") |> data -> do_other_stuff(data) |> data -> println(file_out, data)
    end
end
end

```

And I can optimize by using either `readuntil(data, "prefix")` for text data, or by specifying a bigger block size for binary data and pass it to the `read` function.

@feanor12 what is “anchoring a stream” ?

And a last question, when I try to put the pipe operator on a new line I get the following error:

```julia
readline(file_in)
     |> data -> replace(data, r"some text (?i)" => "$some_variable")
     |> data -> do_other_stuff(data) 
     |> data -> println(file_out, data)

```

```julia
ERROR: syntax: "|>" is not a unary operator

```

Is there a possibility to put the pipe operator in a newline, so if I have several operations, or a lot of parameter it improves code readability ?

---

<div class="post-metadata">

### Author: ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)
#### Post date: [April 26, 2022, 10:49am UTC](https://discourse.julialang.org/t/handling-multiple-files-at-the-same-time/80037/7 "2022-04-26T10:49:13Z")

</div>

There is a descriptions of anchors that can be found here : [https://biojulia.net/BufferedStreams.jl/stable/inputstreams.html#Anchors-1](https://biojulia.net/BufferedStreams.jl/stable/inputstreams.html#Anchors-1)

Basically it marks a specific part of the stream that is kept in the buffer even when it is refilled. This makes it easier to deal with partial matches.

To improve the pipe problem there are different packages like Chain.jl, Pipe.jl or Lazy.jl, but if you put `|>` at the end of the lines it should work.

> **[GitHub - jkrumbiegel/Chain.jl: A Julia package for piping a value through a...](https://github.com/jkrumbiegel/Chain.jl)**
>
> A Julia package for piping a value through a series of transformation expressions using a more convenient syntax than Julia's native piping functionality. - GitHub - jkrumbiegel/Chain.jl: A Jul...
