Skip to content

Er suggestions nonmfs #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/static/tutorials.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@
"0005": {
"url": "file-api",
"project": "IPFS",
"title": "IPFS: File API",
"title": "IPFS: Regular File API",
"description": "The IPFS File API provides a way to store and share files in a peer-to-peer storage system",
"lessons": [
"Introducing the File API",
"Adding a file",
"Add a file with the API",
"Read the contents of a file",
"Add files in a folder",
"Listing the files in a directory",
"Getting all the files in a directory tree"
"List the files in a directory",
"Get all of the files in a directory"
]
}
}
20 changes: 10 additions & 10 deletions src/tutorials/0005/01.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@

## IPFS: The InterPlanetary File System

[IPFS](https://ipfs.io/), or the InterPlanetary File System, is a peer-to-peer (P2P) networking protocol used to share data on the distributed web. As its full name suggests, you can think of IPFS as a file system, and it has some unique characteristics that make it ideal for safe, decentralized sharing.
[IPFS](https://ipfs.io/) is a peer-to-peer (P2P) networking protocol used to share data on the distributed web. You can think of it as a file system with some unique characteristics that make it ideal for safe, decentralized sharing.

If you haven't yet done so, we encourage you to check out our [Decentralized Data Structures tutorial](https://proto.school/#/data-structures/), where you can learn all about the decentralized web and how it compares to the web you're accustomed to. There you'll learn all about content addressing, cryptographic hashing, Content Identifiers (CIDs), and sharing with peers, all of which you'll need to understand to make the most of this tutorial on IPFS.
If you haven't yet done so, we encourage you to check out our [Decentralized Data Structures](https://proto.school/#/data-structures/) tutorial, to learn all about the decentralized web and how it compares to the one you're accustomed to. There you'll learn all about content addressing, cryptographic hashing, Content Identifiers (CIDs), and sharing with peers, all of which you'll need to understand to make the most of this tutorial.

## File API vs DAG API
## The File API vs the DAG API

You can store multiple types of data in the IPFS peer-to-peer data storage system. If you've gone through our [Decentralized Data Structures tutorial](https://proto.school/#/data-structures/), or even the [Blogging on the Decentralized Web tutorial](https://proto.school/#/blog), you already know you can store key value objects in the network.
You can store multiple types of data with IPFS. If you've gone through our Decentralized Data Structures tutorialor even [Blogging on the Decentralized Web](https://proto.school/#/blog)you already know you can store primitives, objects and arrays in the network.

Storing key value objects is an interesting, but limited, use case. What if you want to share a picture of a kitten, how would you go about uploading that file into the network and providing a way for all your friends to see it? Or what about a funny video? How should the file be placed in the directed acyclic graph, in a single block or split into chunks?
Storing these types of data is an interesting, but limited, use case. What if you want to share a picture of a kitten? How would you upload it to the network and provide a way for your friends to see it? What about a larger file, such as a funny video? How should the file be placed in the Directed Acyclic Graph (DAG) — in a single block or split into chunks?

You can look at the File API as an abstraction layer above the DAG API, which takes care of getting files ready to be placed in the network, as well as knowing how to access them. The details of what this API actually does will be covered later in this tutorial.
You can think of the File API as an abstraction layer above the DAG API. The File API prepares files to be placed in the network, and ensures that IPFS knows how to access them. The details of what this API actually does will be covered later in this tutorial.

## Regular File API vs Mutable File System Files API
## The Regular File API vs the MFS File API

You may have already read our [Mutable File System tutorial](https://proto.school/#/mutable-file-system), and if so you may be asking yourself "I've already learned how to use files on IPFS, how will this be any different?".
If you've read our [Mutable File System tutorial](https://proto.school/#/mutable-file-system), you may be thinking, "I've already learned how to use files on IPFS. How will this be any different?"

The Mutable File System (MFS) provides a File API which was built with the purpose of replicating file system operations that you are probably familiar with, such as `mkdir`, `ls`, `cp`, among others. However, the way that content is addressed in IPFS makes it an immutable file system. The address to a file or directory depends on its contents and, as such, modifying a file, or adding a new file to a directory, will result in an entirely new address for it.
The Mutable File System (MFS) provides a File API designed to replicate familiar file-system operations such as `mkdir`, `ls`, `cp`, and others. However, the way that content is addressed in IPFS makes it an immutable file system. The address to a file or directory depends on its contents, so any change to a file will result in an entirely new address. The MFS File APIbuilds a familiar looking file system with regular paths — like `/some/stuff` — in the local IPFS node, which hides the complexity of immutable content addressing.

Therefore, despite being very useful, the abstraction the Mutable File System provides hides some of the inner workings of IPFS. The Regular File API we will discuss in this tutorial is a more barebones approach of using files in IPFS, not providing as much functionality through powerful abstractions as MFS, but helping you understand what you are actually doing in the file system.
Although MFS is very useful, the abstraction it provides hides some of the inner workings of IPFS. The Regular File API we will discuss here is instead a "bare bones" approach to managing files in IPFS. It trades the powerful abstractions of MFS for a scheme which helps you understand what is actually happening in the file system.

11 changes: 6 additions & 5 deletions src/tutorials/0005/02.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
## Working with files in ProtoSchool
Here in our ProtoSchool tutorials, we create a new IPFS node for you in the browser each time you hit the "Submit" button in a lesson. Whenever you see `ipfs.someMethod()` in our lessons, `ipfs` is a variable that refers to your IPFS instance, also known as a node. The actions that you take only affect your own IPFS node, not nodes belonging to your peers.

We're creating your IPFS node behind the scenes so you can focus on the content of our lessons, but eventually you'll need to learn to host your own node locally by installing IPFS and running a daemon in your terminal. When you're ready to experiment, you can find instructions for [installing IPFS](https://docs.ipfs.io/guides/guides/install/) and [initializing your node](https://docs.ipfs.io/introduction/usage/#initialize-the-repository) in our docs.
We create this special IPFS node behind the scenes, so you can focus on the content of our lessons. To host a fully functional IPFS node of your own, though, IPFS must be installed on your machine, and a local daemon running in your terminal. If you haven't already experimented with this, visit our docs to learn how to [install IPFS](https://docs.ipfs.io/guides/guides/install/) and [initialize your node](https://docs.ipfs.io/introduction/usage/#initialize-the-repository).

As mentioned previously, the methods discussed in this tutorial are part of the [Files API](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md), you can check the documentation for more specific details such as options for each API function.
As mentioned previously, the methods discussed in this tutorial are part of the [Files API](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md). Check the documentation for more specific details, such as options for each API function.

## Uploading files in the exercise

As we will be working with adding files to and getting files from an IPFS node, we will need some files to experiment with. For this purpose, there is an upload file step in each code exercise of this tutorial.

## Add a file

Let's start by learning how to add a file to your IPFS node. We do this by executing the following expression:
First let's learn how to add a file to your IPFS node. We'll do this by executing the following expression:

```javascript
await ipfs.add(data, [options], [callback])
Expand All @@ -33,6 +33,7 @@ The result of this `Promise` is an array of objects with the following structure
}
```

This `hash` is what we call a `CID`, a generated address based on the content of the node. For a more in depth look of how `CID`s are generated and what they are, feel free to take a look at the [Decentralized data structures tutorial](https://proto.school/#/data-structures).
This `hash` is what we call a `CID`, a generated address based on the content of the node. For a more in depth look of how `CID`s are generated and what they are, feel free to take a look at the [Decentralized data structures](https://proto.school/#/data-structures) tutorial.

In a future lesson, we will learn how to use this `hash`, or `CID`, to get the contents of a file.

In a future lesson, we will learn how to use this `hash`, or `CID`, to get the contents of a file.
12 changes: 6 additions & 6 deletions src/tutorials/0005/03.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
Now that we've learned how to put some files on your IPFS node, we need to learn how can use their addresses ([CID's](https://proto.school/#/data-structures/04)) to get their content. If your familiar with UNIX style commands, you probably know `cat`. The IPFS File API provides a function with that same name to achieve the same purpose, that is, get the contents of a file.
Now that we've learned how to put some files onto your IPFS node, we can use their addresses ([CID's](https://proto.school/#/data-structures/04)) to get their content. If you're familiar with UNIX style commands, you probably know `cat`. The IPFS File API also provides a `cat` function for the same purpose: to get the contents of a file.

## Using `cat`

When we want to get the contents of a file in IPFS, we call the `cat` function:
To get the contents of a file in IPFS, we call the `cat` function:

```javascript
await ipfs.cat(ipfsPath, [options], [callback])
```

The IPFS path can take several formats, you can read about them in the [File API documentation](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#cat). In this lesson, we will use the simplest form, which is the `hash` string present in the objects we receive from the calling the `ipfs.add` function.
The IPFS path can take several formats (you can read about them in the [File API](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#cat) documentation). In this lesson, we will use the simplest one: the `hash` string present in the objects we receive when the `ipfs.add` function is called.

The returned data comes in the form of an `Buffer`. If the file you uploaded is a plain text file, for example a `.txt`, you can read the contents of the file by calling `result.toString('utf8')`.
The returned data comes in the form of an `Buffer`. If you uploaded a plain text file (such as a `.txt`), you can read the contents of the file by calling `result.toString('utf8')`.

For example, if you have the `CID` to a text file whose contents you want to read you can do this:
So if you have the `CID` to a text file whose contents you want to read, you can do this:

```javascript
let bufferedContents = await ipfs.cat(cid) // returns a buffer
let contents = bufferedContents.toString('utf8') // a string
```

When you're ready to try this in the real world, you should note that `cat` method can result in heavy memory usage based on the contents of the file being read. You might want to explore the [catReadableStream](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#catreadablestream) or [catPullStream](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#catpullstream) methods instead.
When you're ready to try this in the real world, you should note that the `cat` method can result in heavy memory usage, depending on the contents of the file being read. If you find this to be the case, you might want to explore the [catReadableStream](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#catreadablestream) or [catPullStream](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#catpullstream) methods instead.
13 changes: 7 additions & 6 deletions src/tutorials/0005/04.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
When adding one or multiple files to the IPFS node, you usually get back a simple `CID` so you know how to access those files.
When adding one or multiple files to the IPFS node, you usually get back one `CID` per file, which you can use to access their contents.

There is a possibility, however, to place the files you are uploading into a directory. By doing this, you also get back a path for each file you add, as well as a `CID` for the directory itself. We do this by using a special option when calling the `add` function, like this:
If the files are uploaded into a directory, though, IPFS will generate more than one `CID`. You will receive a path for each file you add, as well as a `CID` for the directory itself. We do this by using a special option when calling the `add` function:

```javascript
await ipfs.add(file, { wrapWithDirectory: true })
```

Having a directory with the files you have will allow us to do interesting things with the `ls` and `get` methods, which we will talk about in the next two lessons.
Organizing files into a directory in this way will enable us to do interesting things with the `ls` and `get` methods, which we will talk about in the next two lessons.

The `add` function has plenty of other options, which you can check out at the [add section of the IPFS File API documentation](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#add).
The `add` function has many other features, too, which you can check out in the [`add` section](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#add) of the IPFS File API documentation.

## The file argument

When we want to add a file wrapped within a directory, we can no longer simply call the `add` function with the file itself. We need provide a path so that the ipfs node knows which directories to create.
To upload multiple nested directories, the `add` function requires a little more help. We need to provide a path in order for the ipfs node to properly replicate the directory structure.

In these cases, we replace the `file` argument in the `add` function call with an object like:

Expand All @@ -23,4 +23,5 @@ In these cases, we replace the `file` argument in the `add` function call with a
}
```

If we want to add multiple files at once, into a single or multiple directories, we just need to pass to `add` an array of objects like the one shown above.
If we want to add multiple files at once — into a single or multiple directories — we just need to pass an array of objects like the one shown above to the `add` method.

5 changes: 3 additions & 2 deletions src/tutorials/0005/05.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
Now that we have uploaded some files into a directory in our IPFS node, let's learn how we can check the contents of a directory. If you use the terminal frequently, you're familiar with the `ls` command. Well, the Files API provides you with an `ls` function to achieve the same purpose.
Now that we've uploaded some files into a directory in our IPFS node, let's learn how we can check the contents of a directory. If you use the terminal frequently, you're familiar with the `ls` command. Well, the Files API provides you with an `ls` function to achieve the same purpose.

Calling `ls` looks like this:

```javascript
await ifps.ls( ipfsPath )
```

Where path can take multiple formats, the simplest being a pure `CID`. More information on the formats of the ipfs path can be found in the [ls section of the Files API](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#ls).
Where path can take multiple formats, the simplest being a pure `CID`. More information on the formats of the ipfs path can be found in the [`ls` section](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#ls) of the Files API.

14 changes: 10 additions & 4 deletions src/tutorials/0005/06.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Sometimes we want to know more information about an IPFS path, besides its content in case it's a file.
Sometimes we want to know more information about an IPFS path, besides its content (assuming it's a file).

For this purpose, we have the `get` method, which we can use like this:

Expand All @@ -20,10 +20,16 @@ The result from calling this method is an array of objects with the following st
}
```

Why is the returned value an array? This is one of the advantages the `get` method has over `cat`. Now that we know how we can put files into diferent directories in our IPFS node, it would be interesting to have a way to recursively get the contents of a directory. If we provide an IPFS path of a directory to the `get` method, the returned array will contain every subdirectory and every file present inside the specified directory.
Why is the returned value an array? This is one of the advantages the `get` method has over `cat`. Now that we know how to put files into diferent directories in our IPFS node, it would be interesting to have a way to recursively get the contents of a directory. If we provide an IPFS directory path to the `get` method, the returned array will contain every subdirectory and every file present inside the specified directory.

## When should I use `get` and when should I use `cat`

The use case for `cat` is simply to get the contents of a file for which we have an IPFS path.
The use case for `cat` is simply to get the contents of a file for which we have an IPFS path, while the `get` method provides us with a lot of additional information.

On the other hand, the `get` method provides us with more information than the contents of a file. It is able to recursively retrieve every file and subdirectory in a directory, tell us which entries are directories and which are files, inform us of the size of a file, the depth of a file in the directory structure, among many other details.
`get` can:

- Recursively retrieve every file and subdirectory in a directory
- Tell us which entries are directories and which are files
- Inform us of the size of a file
- Pinpoint the depth of a file in the directory structure
- and offer many other details