Java Gold 例題 nio move

```java

import java.io.IOException;
import java.nio.*;

public class FileMoveTest {
    
    private static final long MINIMUM_SIZE = 100 * 1024; // 100KB
    private static final long MEDIUM_SIZE  = 500 * 1024; // 500KB
	
    public static void main(String[] args) throws IOException {
 
		Path sourceDir = Paths.get("src", "images");
		Path minimumDir   = sourceDir.resolve("minimum");
		Path mediumDir = sourceDir.resolve("medium");
		Path largeDir  = sourceDir.resolve("large");
		
		Files.createDirectories(minimumDir);
		Files.createDirectories(mediumDir);
		Files.createDirectories(largeDir);
	
		Files.list(sourceDir)
			 .filter(file -> file.toString().endsWith(".jpg"))
			 .forEach(file -> {
				 try {
					 long fileSize  = Files.size(file);
					 Path targetDir = null;
					 if(fileSize < MINIMUM_SIZE) {
						 targetDir = minimumDir;
					 } else if(fileSize < MEDIUM_SIZE) {
						 targetDir = mediumDir;
					 } else {
						 targetDir = largeDir;
					 }
					 Files.move(file, targetDir.resolve(file.getFileName()),
							 		StandardCopyOption.REPLACE_EXISTING );
					 
				 } catch(IOException e) {
					 System.out.println("error");
				 }
			 });
	}
}
```

`src/images`以下にjpgファイルおよびフォルダがあります。
・food.jpg(90KB)
・drink.jpg(150KB)
・station.jpg(600KB)
・minimum(0KB)


本コード実行後に以下の変更を行いました。
```java
private static final long MINIMUM_SIZE = 300 * 1024; // 300KB
private static final long MEDIUM_SIZE  = 700 * 1024; // 700KB
```
変更後、本コードを再実行しました。
1度目の実行前と2度目の実行後の状態を比較した時、正しい選択肢を1つ選んでください。

A. 
何も起きない

B. 
必ずerrorが表示される

C. 
「medium」「large」ディレクトリが作成される。
1度目の実行時にjpgファイルが、ファイルサイズに応じたフォルダに移動される。
2度目の実行時には、何も起きない。

D.
「medium」「large」ディレクトリが作成される。
1度目の実行時にjpgファイルが、ファイルサイズに応じたフォルダに移動される。
2度目の実行時には、変更された適切なサイズごとのフォルダへ移動される。

E.
「minimum(2)」「medium」「large」ディレクトリが作成される。
1度目の実行時にjpgファイルが、ファイルサイズに応じたフォルダに移動される。
2度目の実行時には、何も起きない。

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

C

1度目の実行
image/に`medium`, `large`フォルダが新規作成されます。
既にフォルダが存在する場合、新規作成されません。
問題文では`minimum`フォルダは既に存在する、とあるので作成されません。

image/に存在するjpgファイルを、ファイルサイズの条件により、適切なフォルダへ移動します。
・food.jpg(90KB)　   →　image/minimum
・drink.jpg(150KB)   → image/medium
・station.jpg(600KB) → image/large

実行前
image/food.jpg
image/drink.jpg
image/station.jpg
image/minimum

実行後
image/minimum/food.jpg
image/medium/drink.jpg
image/large/station.jpg

2度目の実行
image/に新規フォルダは作成されません。
image/階層に存在するjpgファイルをフィルターしていますが存在しません。
jpgファイルの移動は起きません。


補足
```java
Path sourceDir = Paths.get("src", "images");
Path minimumDir = sourceDir.resolve("minimum");
Path mediumDir = sourceDir.resolve("medium");
Path largeDir = sourceDir.resolve("large");

Files.createDirectories(minimumDir);
Files.createDirectories(mediumDir);
Files.createDirectories(largeDir);
```

`Files.createDirectories()` メソッドを使用して、最小、中間、大きなファイル用のディレクトリを作成しています。

```java
Files.list(sourceDir)
			 .filter(file -> file.toString().endsWith(".jpg"))
```
`Files.list(sourceDir)` を使用して、指定したディレクトリ内のファイルをリストアップしています。
`Files.list(sourceDir)`の戻り値は`Stream<Path>`型となるため、ストリームAPIを利用することができます。
`filter(file -> file.toString().endsWith(".jpg"))` を使って、拡張子が.jpgのファイルのみを処理対象としています。

```java
.forEach(file -> {
     try {
         long fileSize  = Files.size(file);
         Path targetDir = null;
         if(fileSize < MINIMUM_SIZE) {
             targetDir = minimumDir;
         } else if(fileSize < MEDIUM_SIZE) {
             targetDir = mediumDir;
         } else {
             targetDir = largeDir;
         }
         Files.move(file, targetDir.resolve(file.getFileName()),
             StandardCopyOption.REPLACE_EXISTING );
```
ファイルのサイズに応じて、適切なディレクトリに移動する処理を行っています。
500KB未満のファイルはminimumDir、500KB以上550KB未満のファイルはmediumDir、それ以上のファイルはlargeDirに移動します。
`Files.move()` メソッドを使用してファイルを移動しており、既に存在する場合は上書きするオプション (StandardCopyOption.REPLACE_EXISTING) を指定しています。

images/階層のフォルダimages/minimum/フォルダなどに存在するファイルを含めて全て整理する場合、
`Files.walkFileTree()`メソッドを利用することができます。


Docment
[`createDirectories`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/nio/file/Files.html#createDirectories(java.nio.file.Path,java.nio.file.attribute.FileAttribute...))
[`move`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/nio/file/Files.html#move(java.nio.file.Path,java.nio.file.Path,java.nio.file.CopyOption...))
[`Files.list`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/nio/file/Files.html#list(java.nio.file.Path))
[`walkFileTree`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/nio/file/Files.html#walkFileTree(java.nio.file.Path,java.nio.file.FileVisitor))


以下のコードを利用すると、1度目の実行後、`MINIMUM_SIZE`および`MEDIUM_SIZE`を修正したものを再実行すると、minimu/　medium/ large/ 以下に存在する（移動された）jpgファイルも移動の対象となります。

```java
try {
    Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
					
            if(Files.isRegularFile(file) && file.toString().endsWith(".jpg")) {
                long fileSize = Files.size(file);
                Path targetDir;
                
                if(fileSize < MINIMUM_SIZE) {
                    targetDir = minimumDir;
                } else if(fileSize < MEDIUM_SIZE) {
                    targetDir = mediumDir;
                } else {
                    targetDir = largeDir;
                }
                Path targetPath = targetDir.resolve(file.getFileName());
                Files.move(file, targetPath, StandardCopyOption.REPLACE_EXISTING);
            }
            return FileVisitResult.CONTINUE;
        }
    });
    
} catch(IOException e) {
	System.out.println("error");
}
```


https://qiita.com/T-ngtj/private/df254aacd05be698199a