mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-23 13:52:26 +08:00
Compare commits
11 Commits
17b34f8f19
...
v2.2.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56c9327a86 | ||
|
|
11eb559998 | ||
|
|
61a612a06a | ||
|
|
2351ab4714 | ||
|
|
88eec858b4 | ||
|
|
14c37b5a5f | ||
|
|
ad8b1d424c | ||
|
|
a9f01d8a69 | ||
|
|
781b89d51a | ||
|
|
073c77e751 | ||
|
|
91a0d3077d |
12
README.md
12
README.md
@@ -4,7 +4,7 @@
|
|||||||
<br/>
|
<br/>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
2. <b>For users who use version below go1.18, you should install v1.x.x. The latest of v1.x.x is v1.4.1. </b>
|
2. <b>For users who use version below go1.18, you should install v1.x.x. The latest of v1.x.x is v1.4.2. </b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet // below go1.18, install latest version of v1.x.x
|
go get github.com/duke-git/lancet // below go1.18, install latest version of v1.x.x
|
||||||
@@ -451,6 +451,12 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
|||||||
- **<big>RsaDecrypt</big>** : decrypt data with ras algorithm.
|
- **<big>RsaDecrypt</big>** : decrypt data with ras algorithm.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaDecrypt)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaDecrypt)]
|
||||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||||
|
- **<big>GenerateRsaKeyPair</big>** : creates rsa private and public key.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#GenerateRsaKeyPair)]
|
||||||
|
- **<big>RsaEncryptOAEP</big>** : encrypts the given data with RSA-OAEP.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaEncryptOAEP)]
|
||||||
|
- **<big>RsaDecryptOAEP</big>** : decrypts the data with RSA-OAEP
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaDecryptOAEP)]
|
||||||
|
|
||||||
<h3 id="datetime"> 7. Datetime package supports date and time format and compare. <a href="#index">index</a></h3>
|
<h3 id="datetime"> 7. Datetime package supports date and time format and compare. <a href="#index">index</a></h3>
|
||||||
|
|
||||||
@@ -703,6 +709,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
- **<big>WriteStringToFile</big>** : write string to target file.
|
- **<big>WriteStringToFile</big>** : write string to target file.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteStringToFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteStringToFile)]
|
||||||
[[play](https://go.dev/play/p/GhLS6d8lH_g)]
|
[[play](https://go.dev/play/p/GhLS6d8lH_g)]
|
||||||
|
- **<big>ReadFile</big>** : read file or url.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#ReadFile)]
|
||||||
|
|
||||||
<h3 id="formatter"> 10. Formatter contains some functions for data formatting. <a href="#index">index</a></h3>
|
<h3 id="formatter"> 10. Formatter contains some functions for data formatting. <a href="#index">index</a></h3>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<br/>
|
<br/>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/duke-git/lancet/releases)
|
[](https://github.com/duke-git/lancet/releases)
|
||||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.4.1。</b>
|
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.4.2。</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
go get github.com/duke-git/lancet// 使用go1.18以下版本, 必须安装v1.x.x版本
|
go get github.com/duke-git/lancet// 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||||
@@ -451,6 +451,12 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
|||||||
- **<big>RsaDecrypt</big>** : 用私钥文件 rsa 解密数据。
|
- **<big>RsaDecrypt</big>** : 用私钥文件 rsa 解密数据。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaDecrypt)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaDecrypt)]
|
||||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||||
|
- **<big>GenerateRsaKeyPair</big>** : 创建rsa公钥私钥和key。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#GenerateRsaKeyPair)]
|
||||||
|
- **<big>RsaEncryptOAEP</big>** : rsa OAEP加密。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaEncryptOAEP)]
|
||||||
|
- **<big>RsaDecryptOAEP</big>** : rsa OAEP解密。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaDecryptOAEP)]
|
||||||
|
|
||||||
<h3 id="datetime"> 7. datetime 日期时间处理包,格式化日期,比较日期。 <a href="#index">回到目录</a></h3>
|
<h3 id="datetime"> 7. datetime 日期时间处理包,格式化日期,比较日期。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
@@ -707,6 +713,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
- **<big>WriteStringToFile</big>** : 将字符串写入文件。
|
- **<big>WriteStringToFile</big>** : 将字符串写入文件。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteStringToFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteStringToFile)]
|
||||||
[[play](https://go.dev/play/p/GhLS6d8lH_g)]
|
[[play](https://go.dev/play/p/GhLS6d8lH_g)]
|
||||||
|
- **<big>ReadFile</big>** : 读取文件或者URL。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadFile)]
|
||||||
|
|
||||||
<h3 id="formatter"> 10. formatter 格式化器包含一些数据格式化处理方法。 <a href="#index">回到目录</a></h3>
|
<h3 id="formatter"> 10. formatter 格式化器包含一些数据格式化处理方法。 <a href="#index">回到目录</a></h3>
|
||||||
|
|
||||||
@@ -1550,6 +1558,8 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
- **<big>IsBlank</big>** : 检查字符串是否为空格或空。
|
- **<big>IsBlank</big>** : 检查字符串是否为空格或空。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#IsBlank)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#IsBlank)]
|
||||||
[[play](https://go.dev/play/p/6zXRH_c0Qd3)]
|
[[play](https://go.dev/play/p/6zXRH_c0Qd3)]
|
||||||
|
- **<big>IsNotBlank</big>** : 检查字符串是否不为空。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#IsNotBlank)]
|
||||||
- **<big>HasPrefixAny</big>** : 检查字符串是否以指定字符串数组中的任何一个开头。
|
- **<big>HasPrefixAny</big>** : 检查字符串是否以指定字符串数组中的任何一个开头。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#HasPrefixAny)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#HasPrefixAny)]
|
||||||
[[play](https://go.dev/play/p/8UUTl2C5slo)]
|
[[play](https://go.dev/play/p/8UUTl2C5slo)]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// ArrayQueue implements queue with slice
|
// ArrayQueue implements queue with slice
|
||||||
type ArrayQueue[T any] struct {
|
type ArrayQueue[T any] struct {
|
||||||
items []T
|
data []T
|
||||||
head int
|
head int
|
||||||
tail int
|
tail int
|
||||||
capacity int
|
capacity int
|
||||||
@@ -21,7 +21,7 @@ type ArrayQueue[T any] struct {
|
|||||||
|
|
||||||
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
||||||
return &ArrayQueue[T]{
|
return &ArrayQueue[T]{
|
||||||
items: make([]T, 0, capacity),
|
data: make([]T, 0, capacity),
|
||||||
head: 0,
|
head: 0,
|
||||||
tail: 0,
|
tail: 0,
|
||||||
capacity: capacity,
|
capacity: capacity,
|
||||||
@@ -33,7 +33,7 @@ func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
|||||||
func (q *ArrayQueue[T]) Data() []T {
|
func (q *ArrayQueue[T]) Data() []T {
|
||||||
items := []T{}
|
items := []T{}
|
||||||
for i := q.head; i < q.tail; i++ {
|
for i := q.head; i < q.tail; i++ {
|
||||||
items = append(items, q.items[i])
|
items = append(items, q.data[i])
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
@@ -55,40 +55,71 @@ func (q *ArrayQueue[T]) IsFull() bool {
|
|||||||
|
|
||||||
// Front return front value of queue
|
// Front return front value of queue
|
||||||
func (q *ArrayQueue[T]) Front() T {
|
func (q *ArrayQueue[T]) Front() T {
|
||||||
return q.items[0]
|
return q.data[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back return back value of queue
|
// Back return back value of queue
|
||||||
func (q *ArrayQueue[T]) Back() T {
|
func (q *ArrayQueue[T]) Back() T {
|
||||||
return q.items[q.size-1]
|
return q.data[q.size-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnQueue put element into queue
|
// EnQueue put element into queue
|
||||||
func (q *ArrayQueue[T]) Enqueue(item T) bool {
|
func (q *ArrayQueue[T]) Enqueue(item T) bool {
|
||||||
if q.head == 0 && q.tail == q.capacity {
|
if q.tail < q.capacity {
|
||||||
return false
|
q.data = append(q.data, item)
|
||||||
} else if q.head != 0 && q.tail == q.capacity {
|
// q.tail++
|
||||||
for i := q.head; i < q.tail; i++ {
|
q.data[q.tail] = item
|
||||||
q.items[i-q.head] = q.items[i]
|
} else {
|
||||||
|
//upgrade
|
||||||
|
if q.head > 0 {
|
||||||
|
for i := 0; i < q.tail-q.head; i++ {
|
||||||
|
q.data[i] = q.data[i+q.head]
|
||||||
|
}
|
||||||
|
q.tail -= q.head
|
||||||
|
q.head = 0
|
||||||
|
} else {
|
||||||
|
if q.capacity < 65536 {
|
||||||
|
if q.capacity == 0 {
|
||||||
|
q.capacity = 1
|
||||||
|
}
|
||||||
|
q.capacity *= 2
|
||||||
|
} else {
|
||||||
|
q.capacity += 2 ^ 16
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := make([]T, q.capacity, q.capacity)
|
||||||
|
copy(tmp, q.data)
|
||||||
|
q.data = tmp
|
||||||
}
|
}
|
||||||
q.tail = q.tail - q.head
|
|
||||||
q.head = 0
|
q.data[q.tail] = item
|
||||||
}
|
}
|
||||||
|
|
||||||
q.items = append(q.items, item)
|
|
||||||
q.tail++
|
q.tail++
|
||||||
q.size++
|
q.size++
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
||||||
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
||||||
var item T
|
var item T
|
||||||
if q.head == q.tail {
|
if q.size == 0 {
|
||||||
return item, false
|
return item, false
|
||||||
}
|
}
|
||||||
item = q.items[q.head]
|
|
||||||
|
item = q.data[q.head]
|
||||||
q.head++
|
q.head++
|
||||||
|
|
||||||
|
if q.head >= 1024 || q.head*2 > q.tail {
|
||||||
|
q.capacity -= q.head
|
||||||
|
q.tail -= q.head
|
||||||
|
tmp := make([]T, q.capacity, q.capacity)
|
||||||
|
copy(tmp, q.data[q.head:])
|
||||||
|
q.data = tmp
|
||||||
|
q.head = 0
|
||||||
|
}
|
||||||
|
|
||||||
q.size--
|
q.size--
|
||||||
return item, true
|
return item, true
|
||||||
}
|
}
|
||||||
@@ -96,7 +127,7 @@ func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
|||||||
// Clear the queue data
|
// Clear the queue data
|
||||||
func (q *ArrayQueue[T]) Clear() {
|
func (q *ArrayQueue[T]) Clear() {
|
||||||
capacity := q.capacity
|
capacity := q.capacity
|
||||||
q.items = make([]T, 0, capacity)
|
q.data = make([]T, 0, capacity)
|
||||||
q.head = 0
|
q.head = 0
|
||||||
q.tail = 0
|
q.tail = 0
|
||||||
q.size = 0
|
q.size = 0
|
||||||
@@ -105,7 +136,7 @@ func (q *ArrayQueue[T]) Clear() {
|
|||||||
|
|
||||||
// Contain checks if the value is in queue or not
|
// Contain checks if the value is in queue or not
|
||||||
func (q *ArrayQueue[T]) Contain(value T) bool {
|
func (q *ArrayQueue[T]) Contain(value T) bool {
|
||||||
for _, v := range q.items {
|
for _, v := range q.data {
|
||||||
if reflect.DeepEqual(v, value) {
|
if reflect.DeepEqual(v, value) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -117,7 +148,7 @@ func (q *ArrayQueue[T]) Contain(value T) bool {
|
|||||||
func (q *ArrayQueue[T]) Print() {
|
func (q *ArrayQueue[T]) Print() {
|
||||||
info := "["
|
info := "["
|
||||||
for i := q.head; i < q.tail; i++ {
|
for i := q.head; i < q.tail; i++ {
|
||||||
info += fmt.Sprintf("%+v, ", q.items[i])
|
info += fmt.Sprintf("%+v, ", q.data[i])
|
||||||
}
|
}
|
||||||
info += "]"
|
info += "]"
|
||||||
fmt.Println(info)
|
fmt.Println(info)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func TestArrayQueue_Enqueue(t *testing.T) {
|
|||||||
|
|
||||||
assert := internal.NewAssert(t, "TestArrayQueue_Enqueue")
|
assert := internal.NewAssert(t, "TestArrayQueue_Enqueue")
|
||||||
|
|
||||||
queue := NewArrayQueue[int](5)
|
queue := NewArrayQueue[int](2)
|
||||||
queue.Enqueue(1)
|
queue.Enqueue(1)
|
||||||
queue.Enqueue(2)
|
queue.Enqueue(2)
|
||||||
queue.Enqueue(3)
|
queue.Enqueue(3)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
- [WriteCsvFile](#WriteCsvFile)
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
- [WriteStringToFile](#WriteStringToFile)
|
- [WriteStringToFile](#WriteStringToFile)
|
||||||
- [WriteBytesToFile](#WriteBytesToFile)
|
- [WriteBytesToFile](#WriteBytesToFile)
|
||||||
|
- [ReadFile](#ReadFile)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -839,3 +840,41 @@ func main() {
|
|||||||
// hello
|
// hello
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ReadFile">ReadFile</span>
|
||||||
|
|
||||||
|
<p>读取文件或者URL</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;"></span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
reader, fn, err := ReadFile("https://httpbin.org/robots.txt")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fn()
|
||||||
|
|
||||||
|
dat, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(dat))
|
||||||
|
// Output:
|
||||||
|
// User-agent: *
|
||||||
|
// Disallow: /deny
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -65,6 +65,9 @@ import (
|
|||||||
- [GenerateRsaKey](#GenerateRsaKey)
|
- [GenerateRsaKey](#GenerateRsaKey)
|
||||||
- [RsaEncrypt](#RsaEncrypt)
|
- [RsaEncrypt](#RsaEncrypt)
|
||||||
- [RsaDecrypt](#RsaDecrypt)
|
- [RsaDecrypt](#RsaDecrypt)
|
||||||
|
- [GenerateRsaKeyPair](#GenerateRsaKeyPair)
|
||||||
|
- [RsaEncryptOAEP](#RsaEncryptOAEP)
|
||||||
|
- [RsaDecryptOAEP](#RsaDecryptOAEP)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
- [WriteCsvFile](#WriteCsvFile)
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
- [WriteStringToFile](#WriteStringToFile)
|
- [WriteStringToFile](#WriteStringToFile)
|
||||||
- [WriteBytesToFile](#WriteBytesToFile)
|
- [WriteBytesToFile](#WriteBytesToFile)
|
||||||
|
- [ReadFile](#ReadFile)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -839,3 +840,41 @@ func main() {
|
|||||||
// hello
|
// hello
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ReadFile">ReadFile</span>
|
||||||
|
|
||||||
|
<p>Read File/URL</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;"> </span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
reader, fn, err := ReadFile("https://httpbin.org/robots.txt")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fn()
|
||||||
|
|
||||||
|
dat, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(dat))
|
||||||
|
// Output:
|
||||||
|
// User-agent: *
|
||||||
|
// Disallow: /deny
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsExist checks if a file or directory exists.
|
// IsExist checks if a file or directory exists.
|
||||||
@@ -491,7 +492,7 @@ func CurrentPath() string {
|
|||||||
var absPath string
|
var absPath string
|
||||||
_, filename, _, ok := runtime.Caller(1)
|
_, filename, _, ok := runtime.Caller(1)
|
||||||
if ok {
|
if ok {
|
||||||
absPath = path.Dir(filename)
|
absPath = filepath.Dir(filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
return absPath
|
return absPath
|
||||||
@@ -624,3 +625,24 @@ func WriteBytesToFile(filepath string, content []byte) error {
|
|||||||
_, err = f.Write(content)
|
_, err = f.Write(content)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadFile get file reader by a url or a local file
|
||||||
|
// Play: todo
|
||||||
|
func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) {
|
||||||
|
switch {
|
||||||
|
case validator.IsUrl(path):
|
||||||
|
resp, err := http.Get(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, func() {}, err
|
||||||
|
}
|
||||||
|
return resp.Body, func() { resp.Body.Close() }, nil
|
||||||
|
case IsExist(path):
|
||||||
|
reader, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, func() {}, err
|
||||||
|
}
|
||||||
|
return reader, func() { reader.Close() }, nil
|
||||||
|
default:
|
||||||
|
return nil, func() {}, errors.New("unknown file type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package fileutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -385,3 +386,20 @@ func ExampleWriteBytesToFile() {
|
|||||||
// Output:
|
// Output:
|
||||||
// hello
|
// hello
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleReadFile() {
|
||||||
|
reader, fn, err := ReadFile("https://httpbin.org/robots.txt")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fn()
|
||||||
|
|
||||||
|
dat, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(dat))
|
||||||
|
// Output:
|
||||||
|
// User-agent: *
|
||||||
|
// Disallow: /deny
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package fileutil
|
package fileutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -457,3 +458,21 @@ func TestWriteBytesToFile(t *testing.T) {
|
|||||||
|
|
||||||
os.Remove(filepath)
|
os.Remove(filepath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadFile(t *testing.T) {
|
||||||
|
reader, close, err := ReadFile("https://httpbin.org/robots.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
defer close()
|
||||||
|
|
||||||
|
dat, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
want := `User-agent: *
|
||||||
|
Disallow: /deny
|
||||||
|
`
|
||||||
|
internal.NewAssert(t, "TestReadFile").Equal(want, string(dat))
|
||||||
|
}
|
||||||
|
|||||||
1
fileutil/testdata/test1.csv
vendored
1
fileutil/testdata/test1.csv
vendored
@@ -1,2 +1,3 @@
|
|||||||
Lili,22,female
|
Lili,22,female
|
||||||
Jim,21,male
|
Jim,21,male
|
||||||
|
|
||||||
|
|||||||
|
1
fileutil/testdata/test2.csv
vendored
1
fileutil/testdata/test2.csv
vendored
@@ -1,2 +1,3 @@
|
|||||||
Lili,22,female
|
Lili,22,female
|
||||||
Jim,21,male
|
Jim,21,male
|
||||||
|
|
||||||
|
|||||||
|
@@ -29,14 +29,11 @@ func RandInt(min, max int) int {
|
|||||||
if min == max {
|
if min == max {
|
||||||
return min
|
return min
|
||||||
}
|
}
|
||||||
|
|
||||||
if max < min {
|
if max < min {
|
||||||
min, max = max, min
|
min, max = max, min
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix: https://github.com/duke-git/lancet/issues/75
|
|
||||||
// r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
// return r.Intn(max-min) + min
|
|
||||||
|
|
||||||
return rand.Intn(max-min) + min
|
return rand.Intn(max-min) + min
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user