{"id":"reading-files-files","slug":"files-and-folders","title":"Files and folders","text":"Everything a program keeps in its variables is gone when it ends. Data that has to last, such as contacts, high scores or a year of measurements, is kept in **files**.\n\n- A **file** is a piece of data stored under a name: a photo, a song, a document, a program. This module reads **text files**, which hold plain text in lines. Any text editor can open and change them, and your `.java` files are text files too.\n- The end of a file's name, such as `.txt`, `.csv` or `.java`, is its **extension**. It tells what kind of data the file holds, and it's part of the name: `scores` and `scores.txt` are two different names. Windows and macOS can hide extensions when they list files, but the extension is still there.\n- A **folder** (also called a directory) holds files and other folders. A file's **path** names the folders on the way to it: `school/biology/cells.txt` is the file `cells.txt` in the folder `biology`, which is in the folder `school`. Windows writes paths with `\\` instead of `/`.\n\n### Where does the program look?\n\nWhen a program opens a file by its name alone, such as `plants.txt`, Java looks for it in the program's **working folder** (or working directory): the folder the program runs in.\n\n- **On your own computer**, when you run a project from an editor such as NetBeans, IntelliJ IDEA or VS Code, the working folder is usually the project's main folder, the one that holds the `src` folder. A file your program reads goes there, next to `src`, not inside it.\n- **On Java Arena** there's no project folder of your own. Instead, each challenge that reads files provides them: the task shows each file with its name and contents, and the check puts the files in your program's working folder before it runs, just like files next to a program on a computer. **Run with my input** gets the same files. Hidden tests give files with other contents, so the program has to really read them.\n\n### A first look\n\nThis program reads the file `plants.txt` and prints a line for each plant in it:\n\n```file plants.txt\nbasil\nmint\nrosemary\n```\n\n```java\nimport java.nio.file.Paths;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        try (Scanner scanner = new Scanner(Paths.get(\"plants.txt\"))) {\n            while (scanner.hasNextLine()) {\n                String line = scanner.nextLine();\n                System.out.println(\"Water the \" + line);\n            }\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n}\n```\n\n```output\nWater the basil\nWater the mint\nWater the rosemary\n```\n\nThe next steps go through this program part by part. For now, find the file's name in `Paths.get(\"plants.txt\")`: that's where the program says which file to read. Put another name there, and the same program reads another file.\n","task":"This challenge gives the file `recipe.txt`, shown below. Fill in its name, so the program prints each line of the recipe after a dash. For the file shown, it prints:\n\n```\n- 2 eggs\n- 1 cup of milk\n- 1 cup of flour\n```\n","kind":"fill","seed":"import java.nio.file.Paths;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        try (Scanner scanner = new Scanner(Paths.get(\"[[recipe.txt]]\"))) {\n            while (scanner.hasNextLine()) {\n                String line = scanner.nextLine();\n                System.out.println(\"- \" + line);\n            }\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n}\n","solution":"import java.nio.file.Paths;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        try (Scanner scanner = new Scanner(Paths.get(\"recipe.txt\"))) {\n            while (scanner.hasNextLine()) {\n                String line = scanner.nextLine();\n                System.out.println(\"- \" + line);\n            }\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n}\n","hints":["The task shows the file's name above its contents.","The whole name goes between the quotes, extension included: `recipe.txt`."],"tests":[{"name":"Test 1","stdin":"","files":{"recipe.txt":"2 eggs\n1 cup of milk\n1 cup of flour\n"},"expect":"- 2 eggs\n- 1 cup of milk\n- 1 cup of flour","hidden":false},{"name":"Test 2","stdin":"","files":{"recipe.txt":"200 g of rice\n1 onion\n2 cups of water\nsalt\n"},"expect":"- 200 g of rice\n- 1 onion\n- 2 cups of water\n- salt","hidden":true}],"require":[],"forbid":[],"more":[{"task":"This program should print every bird in the file `birds.txt` after `Seen: `, but it prints `Error: birds` instead. Fix it. For the file shown below, it prints:\n\n```\nSeen: robin\nSeen: magpie\nSeen: blue tit\n```\n","kind":"code","seed":"import java.nio.file.Paths;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        try (Scanner scanner = new Scanner(Paths.get(\"birds\"))) {\n            while (scanner.hasNextLine()) {\n                String bird = scanner.nextLine();\n                System.out.println(\"Seen: \" + bird);\n            }\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n}\n","solution":"import java.nio.file.Paths;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        try (Scanner scanner = new Scanner(Paths.get(\"birds.txt\"))) {\n            while (scanner.hasNextLine()) {\n                String bird = scanner.nextLine();\n                System.out.println(\"Seen: \" + bird);\n            }\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n}\n","hints":["`Error: birds` means the program looked for a file called `birds`, and there's no file with exactly that name.","The extension is part of the name: `Paths.get(\"birds.txt\")`."],"tests":[{"name":"Test 1","stdin":"","files":{"birds.txt":"robin\nmagpie\nblue tit\n"},"expect":"Seen: robin\nSeen: magpie\nSeen: blue tit","hidden":false},{"name":"Test 2","stdin":"","files":{"birds.txt":"crow\nheron\nsparrow\nwren\n"},"expect":"Seen: crow\nSeen: heron\nSeen: sparrow\nSeen: wren","hidden":true}],"require":[],"forbid":[]},{"task":"A path is text, so the String methods work on it. What does this program print?\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        String path = \"school/biology/cells.txt\";\n        String[] parts = path.split(\"/\");\n        String name = parts[parts.length - 1];\n        System.out.println(\"Folders: \" + (parts.length - 1));\n        System.out.println(\"File: \" + name);\n        System.out.println(\"In: \" + parts[parts.length - 2]);\n        System.out.println(name.endsWith(\".txt\"));\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        String path = \"school/biology/cells.txt\";\n        String[] parts = path.split(\"/\");\n        String name = parts[parts.length - 1];\n        System.out.println(\"Folders: \" + (parts.length - 1));\n        System.out.println(\"File: \" + name);\n        System.out.println(\"In: \" + parts[parts.length - 2]);\n        System.out.println(name.endsWith(\".txt\"));\n    }\n}\n","hints":["Splitting at `/` gives three parts: `school`, `biology` and `cells.txt`. The last part is the file, the others are folders.","`parts[parts.length - 2]` is the part just before the file: the folder the file is in."],"tests":[{"name":"Output","stdin":"","expect":"Folders: 2\nFile: cells.txt\nIn: biology\ntrue","hidden":false}],"require":[],"forbid":[],"lines":["Folders: 2","File: cells.txt","In: biology","true"]}]}