-
Notifications
You must be signed in to change notification settings - Fork 3
/
status.go
145 lines (130 loc) · 3.32 KB
/
status.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Author: yann
// Date: 2022/5/22
// Desc: hdfsrest
package hdfs
import (
"encoding/json"
"fmt"
"github.com/tidwall/gjson"
"io/ioutil"
"net/http"
"path/filepath"
)
const (
ListStatusFormat = "%s/webhdfs/v1%s?op=LISTSTATUS&user.name=%s"
GetFileStatusFormat = "%s/webhdfs/v1%s?op=GETFILESTATUS&user.name=%s"
GetFileChecksumFormat = "%s/webhdfs/v1%s?op=GETFILECHECKSUM&user.name=%s"
TypeFile = "FILE"
TypeDir = "DIRECTORY"
)
type FileStatus struct {
AccesTime int64
BlockSize int64
Group string
Length int64
ModificationTime int64
Owner string
PathSuffix string
Permission string
Replication int64
Type string
}
func (f FileStatus) IsDir() bool {
if f.Type == TypeDir {
return true
}
return false
}
// ListStatus 获取指定路径下列表
func (c *Client) ListStatus(path string) ([]FileStatus, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(ListStatusFormat, c.addr, path, c.user), nil)
if err != nil {
return nil, err
}
resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, GetErrFromBody(resp)
}
all, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var ret []FileStatus
return ret, json.Unmarshal([]byte(gjson.Get(string(all), "FileStatuses.FileStatus").Raw), &ret)
}
// GetFileStatus 获取指定文件的信息
func (c *Client) GetFileStatus(path string) (*FileStatus, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(GetFileStatusFormat, c.addr, path, c.user), nil)
if err != nil {
return nil, err
}
resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, GetErrFromBody(resp)
}
all, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var ret FileStatus
return &ret, json.Unmarshal([]byte(gjson.Get(string(all), "FileStatus").Raw), &ret)
}
// Walk 遍历某个路径下的目录
func (c *Client) Walk(path string, callback func(prefixPath string, status FileStatus)) error {
status, err := c.GetFileStatus(path)
if err != nil {
return err
}
if status.Type != TypeDir {
return ErrPathIsNotDirectory
}
c.recursionDir(path, callback)
return nil
}
func (c *Client) recursionDir(path string, callback func(prefixPath string, status FileStatus)) {
ls, _ := c.ListStatus(path)
if len(ls) == 0 {
return
}
for i := 0; i < len(ls); i++ {
callback(path, ls[i])
if ls[i].Type != TypeDir {
continue
}
c.recursionDir(filepath.Join(path, ls[i].PathSuffix), callback)
}
}
type FileChecksum struct {
Algorithm string
Bytes string
Length int64
}
// GetFileChecksum 获取指定文件的md5值
func (c *Client) GetFileChecksum(path string) (*FileChecksum, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(GetFileChecksumFormat, c.addr, path, c.user), nil)
if err != nil {
return nil, err
}
resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, GetErrFromBody(resp)
}
all, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var ret FileChecksum
return &ret, json.Unmarshal([]byte(gjson.Get(string(all), "FileChecksum").Raw), &ret)
}