สร้าง io.Reader จากไฟล์ในเครื่อง


89

ฉันต้องการเปิดไฟล์ในเครื่องและส่งคืนไฟล์io.Reader. เหตุผลก็คือฉันต้องป้อนไฟล์io.Readerไปยังห้องสมุดที่ฉันใช้เช่น:

func read(r io.Reader) (results []string) {

}

1
อาจจะคุ้มค่าที่จะใช้เวลาในการค้นหารอบ ๆgolang.org/pkgและสำหรับสิ่งที่ดูเหมือนว่าคุณกำลังทำ os, io, io / ioutil และ bufio
twotwotwo

คำตอบ:


117

os.Open ส่งคืนไฟล์ io.Reader

http://play.golang.org/p/BskGT09kxL

package main

import (
    "fmt"
    "io"
    "os"
)

var _ io.Reader = (*os.File)(nil)

func main() {
    fmt.Println("Hello, playground")
}

30
เฮ้ชอบเคล็ดลับในการแสดงว่า (* os.File) เป็น io อ่านโดยไม่สามารถเปิดไฟล์จาก Playground ได้
twotwotwo

@twotwotwo แฮ็คนั้นทำอะไรกันแน่ ฉันสมมติว่าวากยสัมพันธ์ว่าไฟล์ไม่มีอะไรเลยดังนั้นจึงไม่พยายามเปิดอะไรเลย
mschuett

7
@mschuett ไม่มากก็น้อย: เป็นnilตัวชี้ประเภทที่ถูกต้องเพื่อชี้ไปที่os.Fileไฟล์. (ในกรณีนี้คุณไม่สามารถทำอะไรได้เลย) และการvar _ io.Reader = (*os.File)(nil)มอบหมายทำให้คอมไพเลอร์ตรวจสอบว่า*os.Fileเป็นio.Reader(มิฉะนั้นการมอบหมายจะไม่ถูกต้อง) หากคุณไปที่ Playground และเปลี่ยน*os.Fileเป็น*os.Processคุณจะเห็นข้อผิดพลาดที่สร้างขึ้นสำหรับสิ่งที่ไม่ตรงกับอินเทอร์เฟซ
twotwotwo

2
@fabrizioM ตรงที่ในเอกสารระบุว่า * os ไฟล์ใช้ Reader มิฉะนั้นหากไม่มีคำตอบนี้คุณจะคิดออกจากการอ่านเอกสารอย่างเป็นทางการได้อย่างไร? ตกลงฉันเห็นว่าfunc (f *File) Read(b []byte) (n int, err error), Readerเช่นเดียวกับใน
Aliaksandr Kazlou

43

ใช้os.Open () :

func เปิด (สตริงชื่อ) (ไฟล์ * ไฟล์ข้อผิดพลาดผิดพลาด)

Open เปิดไฟล์ที่มีชื่อเพื่ออ่าน หากสำเร็จสามารถใช้วิธีการในไฟล์ที่ส่งคืนเพื่ออ่านได้ ตัวบอกไฟล์ที่เกี่ยวข้องมีโหมด O_RDONLY หากมีข้อผิดพลาดจะเป็นประเภท * PathError

ค่าที่ส่งคืนของประเภท*os.Fileใช้io.Readerอินเทอร์เฟซ


27

ประเภท * os ไฟล์ใช้อินเทอร์เฟซ io.Reader เพื่อให้คุณสามารถส่งคืนไฟล์เป็น Reader แต่ฉันขอแนะนำให้คุณใช้แพ็คเกจbufioหากคุณมีความตั้งใจที่จะอ่านไฟล์ขนาดใหญ่สิ่งนี้:

file, err := os.Open("path/file.ext")
// if err != nil { ... }

return bufio.NewReader(file)

4
คุณช่วยอธิบายให้ละเอียดได้ไหมว่าทำไมคุณถึงแนะนำbufioไฟล์ขนาดใหญ่
Ciro Costa

1
@CiroCosta หากคุณมีไฟล์ Gbs ขนาดใหญ่คุณไม่ต้องการอ่านมันอย่างสมบูรณ์ในหน่วยความจำดังนั้นสำหรับกรณีเหล่านี้เราควรใช้บัฟเฟอร์
Yandry Pozo

รันไทม์ของ go ใช้บัฟเฟอร์ในสถานการณ์ที่เหมาะสมเช่นio Copyจะใช้บัฟเฟอร์พื้นฐานซ้ำหากอินเทอร์เฟซของพวกเขาพร้อมใช้งานมิฉะนั้นจะสร้างบัฟเฟอร์ภายใน
colm.anseo

1
ขอบคุณสำหรับpath/file.ext. ไม่มีคำตอบอื่นใดที่สะกดว่าos.Fileคืออะไร
Azurespot

5

นี่คือตัวอย่างที่เราเปิดไฟล์ข้อความและสร้าง io.Reader จาก * os ที่ส่งคืนไฟล์อินสแตนซ์ f

package main

import (
    "io"
    "os"
)

func main() {
    f, err := os.Open("somefile.txt")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    var r io.Reader
    r = f
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.