# How does Files API - \`ipfs files\` command work

**URL:** <https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344>\
**Category:** Help\
**Created:** [May 23, 2017, 12:07am UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344 "2017-05-23T00:07:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![flyingzumwalt](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/flyingzumwalt/32/12_2.png) [@flyingzumwalt](https://discuss.ipfs.tech/u/flyingzumwalt)\
**Post date:** [May 23, 2017, 12:07am UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344/1 "2017-05-23T00:07:26Z")

</div>

_From @Kubuxu on Mon Jul 04 2016 18:27:17 GMT+0000 (UTC)_  
  
IPFS Files API allows to manipulate unixfs objects (current IPFS files and directories format) in manner similar to normal Unix commands.

How does it work:

IPFS Files API introduces virtual root directory. You can check it content with `ipfs files ls /`.  
You can copy files and directories that were added to IFPS using `ipfs files cp /ipfs/Qmc4xcnns2rA4akaWfGdzdaN8My1ES6zh7yddYZ5mo7n2U /greetings`.

Then you can view content of that directory using `ipfs files ls /greetings` and read file in it using `ipfs files read /greetings/greetings.md`.

You can then modify the structure with different commands: `ipfs files mv /greetings/greetings.md /greetings/greetings.txt`, note that will change hash of the `/greetings` directory. You can check new hash using `ipfs files stat --hash /greetings`.

If you have any more questions, please ask.  
  
  
_Copied from original issue: [How does Files API - `ipfs files` command work. · Issue #143 · ipfs-inactive/faq · GitHub](https://github.com/ipfs/faq/issues/143)_

---

<div class="post-metadata">

**Author:** ![flyingzumwalt](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/flyingzumwalt/32/12_2.png) [@flyingzumwalt](https://discuss.ipfs.tech/u/flyingzumwalt)\
**Post date:** [May 23, 2017, 12:07am UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344/2 "2017-05-23T00:07:59Z")

</div>

_From @Ghoughpteighbteau on Fri Jul 08 2016 21:45:59 GMT+0000 (UTC)_  
  
So here’s me playing around with this feature.

```bash
~ $ ipfs files ls
~ $ ipfs files cp /ipfs/QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 /examples
~ $ ipfs files ls -l 
examples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
~ $ ipfs files ls -l /examples | column -t
Makefile QmVxEtpVTAjneTSC2vZukww5KfLMnHFsBA3XQZnMHNXXDf 157
api QmavsNYkgNcrNGgcmF6iq1SrkaaFNJVzqEnfVfdixFpPsk 0
basics QmYEcwYnCYb9CU6ipxRJvkFmBPwgRY4fD8eLLAj3rmetyi 0
bootstrap QmXRv4gRdokiarChpxF33jr35b6rexADEcdkwoFqKBRhzZ 0
config QmXhaJNHgzRaWqkdnmGJSPuxc12AueXeLda8F736MqPTbd 0
data QmTitSFQFQeBMZRDsGEvzdNgPnwx7coBCQxEYvNzgWPkK8 0
git Qmf6cuHtrDbqoKH2L8y9MtQUmGyNksR5RoKVNVvN23BG4G 0
graphmd QmfT4cEw9zezKaV6wF9aELFtpuovxFCR8CXSkUb6enAgw8 0
init QmTSE278Mb1dLXtco1wBbqaUCzD17hxRKGbqhZtUbNL3Vz 0
ipns QmUTWHFReYWNf6DX2GKy1kGXFecxQPaLTyZjVf2zKr28xu 0
network QmRPg57F8V46vvAGjdjARPtSMYj6wBicf482MJfen3M4LT 0
pinning QmXQNjQFBv8DxjgW1artxcXdhReFoaGRxhKqYgiMGPJ9o1 0
published-version QmPtqzMtd7ZLBWu9sF1xSUDfRZ6kkVnactBMKHdsMC1ZtJ 188
snapshots QmYuo1vhfDNTAmTPakchttvamQj6aLFjv6J5oeUJZhC99M 0
videos QmaJ8xTbRqTFBKEfePvL5tS3iAZJUMRWtUX9k8Pm9Sh8pT 0
websites QmZdWW55p6YTkFnGZHUmdVZjVKaBA745FENzftoYdapU9g 0
~ $ ipfs files cp /ipfs/QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 /test
~ $ ipfs files ls -l 
examples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
test QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
~ $ # gaaah, no columns....
~ $ ipfs files ls -l | column -t
examples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
test QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
~ $ ipfs files rm -r /test
~ $ ipfs files mkdir /test
~ $ ipfs files cp /ipfs/QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 /test/otherExamples
~ $ ipfs files ls -l | column -t
examples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
test QmdQ3wVuxPPSjbihiDKndwYBFQDtGWznEdmnjLEpdEphas 0
~ $ ipfs files ls -l /test | column -t
otherExamples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
~ $ ipfs files stat /
QmTffJW1tzPwikLeCAFw7t4DbZidVGwVM1oMs96PTy25tk
Size: 0
CumulativeSize: 794139
ChildBlocks: 2
Type: directory
~ $ ipfs files cp ./pic/dukesOfNyan.gif /test/dukesOfNyan.gif
Error: Paths must start with a leading slash.
~ $ # I expected that to work...
~ $ ipfs add ./pic/dukesOfNyan.gif 
added QmeFBEVocqUpuob62umabRuSXERGFwF6TVK3ZqBAdv3VjL dukesOfNyan.gif
~ $ ipfs files cp /ipfs/QmeFBEVocqUpuob62umabRuSXERGFwF6TVK3ZqBAdv3VjL /test/dukesOfNyan.gif
~ $ ipfs files ls -l /test | column -t
dukesOfNyan.gif QmeFBEVocqUpuob62umabRuSXERGFwF6TVK3ZqBAdv3VjL 19411092
otherExamples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
~ $ ipfs files ls -l / | column -t
examples QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7 0
test QmX8NbuNEEqqxDNU1GuXyQST83EpqRt3gQweZeAGzpJFGc 0

```

So a few questions. Is this meant as a convenient editor for adding IPFS directory objects?

Does this have an advantage over just editing a directory in the local file system and adding that?

I see root has a hash as well. If someone requests that hash, will I give it to them?

When I changed `/test` from being `QmdQ3wVuxPPSjbihiDKndwYBFQDtGWznEdmnjLEpdEphas` to `QmX8NbuNEEqqxDNU1GuXyQST83EpqRt3gQweZeAGzpJFGc` I noticed that the old versions of /test was still stored

```bash
~ $ ipfs object get /ipfs/QmdQ3wVuxPPSjbihiDKndwYBFQDtGWznEdmnjLEpdEphas
{"Links":[{"Name":"otherExamples","Hash":"QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7","Size":396987}],"Data":"\u0008\u0001"}
~ $ ipfs object get /ipfs/QmX8NbuNEEqqxDNU1GuXyQST83EpqRt3gQweZeAGzpJFGc
{"Links":[{"Name":"dukesOfNyan.gif","Hash":"QmeFBEVocqUpuob62umabRuSXERGFwF6TVK3ZqBAdv3VjL","Size":19415747},{"Name":"otherExamples","Hash":"QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7","Size":396987}],"Data":"\u0008\u0001"}

```

So each modification done in `ipfs files` is added to ipfs. Is that what the ipfs files flush command is for? To avoid constantly adding changes to ipfs?

I notice that entries into the files API are not pinned, should they be?

Finally I’m trying to get an overall sense of what this command is intended for long term. This kinda seems like a porcelain command, more than a plumbing. Long term, are we all going to have an IPFS ‘drive’, that our file browsers understand, where we organize the contents of IPFS?

---

<div class="post-metadata">

**Author:** ![flyingzumwalt](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/flyingzumwalt/32/12_2.png) [@flyingzumwalt](https://discuss.ipfs.tech/u/flyingzumwalt)\
**Post date:** [May 23, 2017, 12:08am UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344/3 "2017-05-23T00:08:25Z")

</div>

_From @whyrusleeping on Fri Jul 08 2016 22:05:03 GMT+0000 (UTC)_  
  
\> Is this meant as a convenient editor for adding IPFS directory objects?

Yes, among other things

> Does this have an advantage over just editing a directory in the local file system and adding that?

depends on what your usecase is, `ipfs add` actually uses this code under the hood, so performance should be identical

> So each modification done in ipfs files is added to ipfs. Is that what the ipfs files flush command is for?

Each modification is stored _unless_ you use the `--flush=false` option. If you set flush to false, it will not write intermediate objects out until you run a command on that branch with flush true, or you run `ipfs files flush` on the directory/object in question

> I notice that entries into the files API are not pinned, should they be?

This one is tricky, and something we havent quite finished. Stuff in the files API are not currently pinned, and they should not be pinned _recursively_. The reason for this is because one use case we want to explicitly support is `ipfs files cp /ipfs/Qm20TBDataSet /somewhere`, and be able to operate on that dataset without pulling it entirely local. Towards this, we are going to implement a new pin type called ‘best effort’ that will keep what you have local, local. Until then, be wary running a gc if youre playing with the files api.

> Long term, are we all going to have an IPFS ‘drive’, that our file browsers understand, where we organize the contents of IPFS?

Thats one idea 🙂 And one i very much support

---

<div class="post-metadata">

**Author:** ![tuan3w](https://avatars.discourse-cdn.com/v4/letter/t/91b2a8/32.png) [@tuan3w](https://discuss.ipfs.tech/u/tuan3w)\
**Post date:** [June 8, 2018, 1:30pm UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344/4 "2018-06-08T13:30:53Z")

</div>

Hi everyone,  
I’m still cannot get the purpose of files API. I try to read spec and searching around, but I couldn’t have any idea to persuade me. So I have several questions about files API and hope someone can help me clear my confusion.

> IPFS Files API introduces virtual root directory. You can check it content with ipfs files ls /.  
> You can copy files and directories that were added to IFPS using ipfs files cp /ipfs/Qmc4xcnns2rA4akaWfGdzdaN8My1ES6zh7yddYZ5mo7n2U /greetings.

1. Does it mean it creates a symlink from IPFS to our local root directory or it just copy data from IPFS to our local directory? If it’s a symlink, how can I find corresponding file in IPFS?
2. When we call some function like :  
ipfs files mkdir   
ipfs files write   
what will happen ? Does it affect IPFS storage ?
3. Why we need a virtual directory instead of storing in a real directory ? As I understand, IPFS client can be browser, so I think people might want to create virtual directory to manage generated data. Does it only a reason or am I missing something?
4. And final question, I can read file though API ([https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesread](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesread)), so basicly does anyone can access to it or they have my private key? Reason I ask this question because, if I put some file in to ‘/somepath/myfile’, if any one can access file through that path, it would be nicer than very long meaningless hash name and I can update file content without using IPNS, which is very slow to update?

Thanks for your clarification.

---

<div class="post-metadata">

**Author:** ![Mr0grog](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/mr0grog/32/2460_2.png) [@Mr0grog](https://discuss.ipfs.tech/u/Mr0grog)\
**Post date:** [June 9, 2018, 3:13am UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344/5 "2018-06-09T03:13:31Z")

</div>

Hey @tuan3w, the idea of the files API (you might also see it referred to as “MFS” or Mutable FileSystem) is generally to make it easier to edit and organize files in IPFS. Since nothing can be changed after it’s added to IPFS (or: changing a file/directory change’s its hash, which basically means you’re making a _new_ file), doing something that might simple on your hard drive, like renaming a file, can be pretty complicated in IPFS.

For example, if you had a directory structure like:

```auto
/documents
    /ipfs-introduction
        - overview.txt
        - use-cases.txt

```

And you renamed `overview.txt` to `introduction.txt`, you’d have to:

1. Make a copy of the `ipfs-introduction` directory and change the name of the file in it.
2. Add the new directory to IPFS.
3. Make a copy of the `documents` directory and change the hash for the `ipfs-introduction` directory in it to point to the new one.
4. Add _that_ new directory to IPFS.
5. Get the new hash for `documents` so you can share it.

To make that easier, the files API gives you some basic Unix-style commands (`cp`, `ls`, `mkdir`, `mv`, `rm`) to manipulate files. When you use them, IPFS takes care of managing all the different hashes and links that have to change. So, to do the above operation, you can just:

1. Move the file:

2. Get the hash:

Does that make sense? Hopefully that helps clarify some of your original questions:

> [@tuan3w](#):
>
> Does it mean it creates a symlink from IPFS to our local root directory or it just copy data

`ipfs files cp` doesn’t make a copy; it just adds a pointer to the hash of the file you are copying. So in your example, you added a pointer named `greetings` in the IPFS object that represents the root directory whose value is `/ipfs/Qmc4xcnns2rA4akaWfGdzdaN8My1ES6zh7yddYZ5mo7n2U`.

> When we call some function like `ipfs files mkdir` and `ipfs files write`

On the other hand, `ipfs files write` _adds_ the data to IPFS. It’s kind of like `ipfs add [filename]`, except it doesn’t just add it to the IPFS network with a hash — it _also_ puts it in the MFS root directory with a nice name. After that, you’ll have:

- The original file on your computer’s filesystem
- A copy of the file in IPFS
- Two pointers to the file in IPFS: one as just a regular hash and one from MFS

> does anyone can access to it or they have my private key?

Right now, the only way to access MFS content is through the files API. That means someone has to have access to your IPFS node’s API in order to read. The API is normally private (only your computer can access it). You can change that, but I don’t recommend it.

---

<div class="post-metadata">

**Author:** ![tuan3w](https://avatars.discourse-cdn.com/v4/letter/t/91b2a8/32.png) [@tuan3w](https://discuss.ipfs.tech/u/tuan3w)\
**Post date:** [June 9, 2018, 8:13am UTC](https://discuss.ipfs.tech/t/how-does-files-api-ipfs-files-command-work/344/6 "2018-06-09T08:13:35Z")

</div>

Oh, thank @Mr0grog for your clarification. It’s very insteresting.  
Before this, in order to modify structure of a folder, I have to use `ipfs object patch` and store hash somewhere for retrieval purpose. Now, using `files` API can make everything much easier 😃 .
