0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Go/Java は Windows の MAX_PATH(260) を超えるファイルにアクセスできるのか

Last updated at Posted at 2020-05-06

調査した結果、特に何もしなくてもアクセスできるようだった。
Windows の場合 CreateFile API を通じてさらにパスのプリフィクスに \?\ をつける(「\?\C:\Windows\test.txt」みたいに)必要があるが、Go/Java だと内部でやってくれる模様。

まずは Go の場合のテスト

main.go
package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/blono/win" // Fork of lxn/win see https://qiita.com/manymanyuni/items/c41f5bf0fd141e299336
)

func main() {
	longPath := `C:\Users\manymanyuni\Desktop\long\loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\loooooooooooooooooooooooooooooong.txt`
	file := win.CreateFile(`\\?\`+longPath, win.GENERIC_ALL, 0, nil, win.CREATE_ALWAYS, win.FILE_ATTRIBUTE_NORMAL, win.HANDLE(unsafe.Pointer(nil)))
	var c uint32 = 8
	win.WriteFile(file, uintptr(unsafe.Pointer(winut.NewUTF16("test"))), c, &c, nil)
	win.CloseHandle(file)

	bytes, err := ioutil.ReadFile(longPath) // OK!
	if err != nil {
		fmt.Printf("%v", err)
	}
	fmt.Println(string(bytes))

	bytes, err = ioutil.ReadFile(`\\?\` + longPath) // OK!
	if err != nil {
		fmt.Printf("%v", err)
	}
	fmt.Println(string(bytes))
}

ちなみに、ioutil.ReadFile に渡すパスを「\?\」で始めても動いたので、Go の Windows 実装は見てないが恐らくこのあたりのプリフィクスを考慮しながら CreateFileW をたたいているのだと思われる。

さらに、Java の場合のテスト

Test.java
import java.io.FileReader;
import java.io.IOException;

public class Test {
    public static void main(String args[]) throws IOException {
        var path = "C:\\Users\\manymanyuni\\Desktop\\long\\loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\\loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\\loooooooooooooooooooooooooooooong.txt";

        try (var reader = new FileReader(path)) {
            System.out.println(reader.read());
        }
    }
}

使った Java のバージョンはこちら
openjdk version "11.0.3" 2019-04-16 LTS
OpenJDK Runtime Environment Corretto-11.0.3.7.1 (build 11.0.3+7-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.3.7.1 (build 11.0.3+7-LTS, mixed mode)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?