@@ -45,7 +45,7 @@ func (f *File) Close() error {
45
45
}
46
46
47
47
// Read reads data into the provided byte slice.
48
- func (f * File ) Read (_ []byte ) (n int , err error ) {
48
+ func (f * File ) Read (p []byte ) (n int , err error ) {
49
49
shareName := getShareName (f .name )
50
50
51
51
defer f .sendOperationStats (& FileLog {
@@ -55,10 +55,49 @@ func (f *File) Read(_ []byte) (n int, err error) {
55
55
Message : nil ,
56
56
}, time .Now ())
57
57
58
- // TODO: Implement proper file reading using Azure SDK
59
- // This would require a file client and proper offset handling
60
- // For now, return not implemented as we need more context
61
- return 0 , ErrReadNotImplemented
58
+ if f .conn == nil {
59
+ return 0 , ErrShareClientNotInitialized
60
+ }
61
+
62
+ // Download file content from Azure
63
+ downloadResult , err := f .conn .DownloadFile (f .ctx , map [string ]any {
64
+ "path" : f .name ,
65
+ "offset" : f .offset ,
66
+ "length" : len (p ),
67
+ })
68
+ if err != nil {
69
+ // If the file doesn't exist or has no content, return EOF
70
+ if strings .Contains (err .Error (), "ResourceNotFound" ) || strings .Contains (err .Error (), "InvalidRange" ) {
71
+ return 0 , io .EOF
72
+ }
73
+ return 0 , fmt .Errorf ("failed to download file %s: %w" , f .name , err )
74
+ }
75
+
76
+ // Extract the response body
77
+ response , ok := downloadResult .(map [string ]any )
78
+ if ! ok {
79
+ return 0 , fmt .Errorf ("invalid download response format" )
80
+ }
81
+
82
+ body , ok := response ["body" ].(io.ReadCloser )
83
+ if ! ok {
84
+ return 0 , fmt .Errorf ("invalid response body" )
85
+ }
86
+
87
+ // Read data into the provided buffer
88
+ n , err = body .Read (p )
89
+ if err != nil && err != io .EOF {
90
+ body .Close ()
91
+ return n , fmt .Errorf ("failed to read from response body: %w" , err )
92
+ }
93
+
94
+ // Update offset
95
+ f .offset += int64 (n )
96
+
97
+ // Store body for potential reuse
98
+ f .body = body
99
+
100
+ return n , err
62
101
}
63
102
64
103
// ReadAt reads data into the provided byte slice starting at the specified offset.
@@ -84,7 +123,7 @@ func (f *File) Seek(offset int64, whence int) (int64, error) {
84
123
}
85
124
86
125
// Write writes data from the provided byte slice to the file.
87
- func (f * File ) Write (_ []byte ) (n int , err error ) {
126
+ func (f * File ) Write (p []byte ) (n int , err error ) {
88
127
shareName := getShareName (f .name )
89
128
90
129
defer f .sendOperationStats (& FileLog {
@@ -94,10 +133,42 @@ func (f *File) Write(_ []byte) (n int, err error) {
94
133
Message : nil ,
95
134
}, time .Now ())
96
135
97
- // TODO: Implement proper file writing using Azure SDK
98
- // This would require a file client and proper offset handling
99
- // For now, return not implemented as we need more context
100
- return 0 , ErrWriteNotImplemented
136
+ if f .conn == nil {
137
+ return 0 , ErrShareClientNotInitialized
138
+ }
139
+
140
+ // For the first write (offset 0), we need to create the file with content
141
+ if f .offset == 0 {
142
+ // Create a reader from the byte slice
143
+ reader := & readSeekCloser {strings .NewReader (string (p ))}
144
+
145
+ // Upload the data range to Azure starting at offset 0
146
+ _ , err = f .conn .UploadRange (f .ctx , 0 , reader , map [string ]any {
147
+ "path" : f .name ,
148
+ })
149
+ if err != nil {
150
+ return 0 , fmt .Errorf ("failed to upload range to file %s: %w" , f .name , err )
151
+ }
152
+ } else {
153
+ // For subsequent writes, append to existing content
154
+ reader := & readSeekCloser {strings .NewReader (string (p ))}
155
+
156
+ // Upload the data range to Azure at the current offset
157
+ _ , err = f .conn .UploadRange (f .ctx , f .offset , reader , map [string ]any {
158
+ "path" : f .name ,
159
+ })
160
+ if err != nil {
161
+ return 0 , fmt .Errorf ("failed to upload range to file %s: %w" , f .name , err )
162
+ }
163
+ }
164
+
165
+ // Update offset and size
166
+ f .offset += int64 (len (p ))
167
+ if f .offset > f .size {
168
+ f .size = f .offset
169
+ }
170
+
171
+ return len (p ), nil
101
172
}
102
173
103
174
// WriteAt writes data from the provided byte slice to the file starting at the specified offset.
@@ -122,6 +193,37 @@ func (f *File) ReadAll() (fileSystem.RowReader, error) {
122
193
}, nil
123
194
}
124
195
196
+ // GetProperties retrieves file properties from Azure
197
+ func (f * File ) GetProperties () (map [string ]any , error ) {
198
+ if f .conn == nil {
199
+ return nil , ErrShareClientNotInitialized
200
+ }
201
+
202
+ result , err := f .conn .GetProperties (f .ctx , map [string ]any {
203
+ "path" : f .name ,
204
+ })
205
+ if err != nil {
206
+ return nil , fmt .Errorf ("failed to get properties for file %s: %w" , f .name , err )
207
+ }
208
+
209
+ props , ok := result .(map [string ]any )
210
+ if ! ok {
211
+ return nil , fmt .Errorf ("invalid properties response format" )
212
+ }
213
+
214
+ return props , nil
215
+ }
216
+
217
+ // readSeekCloser wraps strings.Reader to implement io.ReadSeekCloser
218
+ type readSeekCloser struct {
219
+ * strings.Reader
220
+ }
221
+
222
+ func (r * readSeekCloser ) Close () error {
223
+ // strings.Reader doesn't need to be closed
224
+ return nil
225
+ }
226
+
125
227
// azureRowReader implements the RowReader interface for Azure files.
126
228
type azureRowReader struct {
127
229
file * File
0 commit comments