Có những thứ như API tệp HTML5 để truy cập các tệp cục bộ được chọn bởi người dùng, mà không tải lên chúng ở bất cứ đâu.HTML5 File API to access local files picked by user, without uploading them anywhere.
Nó là tính năng khá mới, nhưng được hỗ trợ bởi hầu hết các trình duyệt hiện đại.
Tôi thực sự khuyên bạn nên kiểm tra bài viết tuyệt vời này để xem, làm thế nào bạn có thể sử dụng nó.
Có một vấn đề với điều này, bạn không thể đọc các tệp lớn [~ 400 MB trở lên] vì các chức năng Fileapi thẳng tiến đang cố gắng tải toàn bộ tệp vào bộ nhớ.can't read big files [~400 MB and larger] because straight forward FileAPI functions attempting to load entire file into memory.
Nếu bạn cần đọc các tệp lớn hoặc tìm kiếm một cái gì đó ở đó hoặc điều hướng theo chỉ mục dòng, hãy kiểm tra vải lanh của tôi, cho phép bạn đọc, điều hướng và tìm kiếm trong các tệp có kích thước. Hãy thử nó trong jsfiddle! Nó rất dễ sử dụng:LineNavigator, which allows you to read, navigate and search in files of any size. Try it in jsFiddle! It is super easy to use:
var navigator = new FileNavigator[file];
navigator.readSomeLines[0, function linesReadHandler[err, index, lines, eof, progress] {
// Some error
if [err] return;
// Process this line bucket
for [var i = 0; i < lines.length; i++] {
var line = lines[i];
// Do something with it
}
// End of file
if [eof] return;
// Continue reading
navigator.readSomeLines[index + lines.length, linesReadHandler];
}];
Gần đây, tôi đã làm việc trên một dự án phụ, dựa trên việc đọc và thao tác các tệp để tạo hình thu nhỏ tùy chỉnh cho các mặt số tốc độ của Vivaldi trình duyệt. Tôi đã có thể thực hiện tất cả bên trong trình duyệt, mà không cần xử lý phía máy chủ và tôi muốn chia sẻ với bạn mọi thứ mà tôi đã học được. Hướng dẫn này bao gồm: Để cho phép người dùng của bạn chọn một tệp từ thiết bị của họ, trước tiên bạn sẽ phải tạo một Để thực sự nhận được các tệp từ đầu vào này, bạn sẽ cần truy cập thuộc tính Cách bạn làm sẽ phụ thuộc vào khung mà bạn sử dụng. Để làm cho hướng dẫn này được áp dụng rộng rãi nhất có thể, chúng tôi sẽ sử dụng vani JS. Kết quả được chọn là một đối tượng Đầu vào tệp cung cấp cho chúng tôi các đối tượng Ngoài Hướng dẫn chuyên sâu về API Filereader và URL đối tượng.
Chọn tệp từ hệ thống tập tin
input
với loại tệp.file.files
của phần tử đầu vào. Tốt nhất là làm điều đó bằng cách đăng ký trình nghe sự kiện thay đổi trên phần tử đầu vào. Bằng cách này, một chức năng gọi lại sẽ được gọi mỗi khi người dùng chọn một tệp.change event listener on the input
element. This way a callback function will be called every time a user selects a file.File
.selectedFile is a File
object.Thuộc tính của các tập tin
File
, do đó, ngoài chính nội dung của tệp, chúng tôi còn có quyền truy cập vào một số thông tin bổ sung, chẳng hạn như:name
- Tên của tệp, bao gồm cả phần mở rộng nhưng không có đường dẫn [ví dụ: "cat_photo.png"]size
- Kích thước của tệp tính bằng byte. Để có được kích thước ở định dạng dễ đọc hơn của con người, bạn có thể sử dụng thư viện như tệp hoặc byte. Đối với các trường hợp sử dụng đơn giản, bạn thậm chí có thể viết logic chuyển đổi của riêng bạn.type
- Loại MIME của tệp [ví dụ: "Text/Plain", "Image/PNG"]lastModified
- Ngày sửa đổi cuối cùng của tệp, được biểu thị dưới dạng số mili giây kể từ thời đại Unix [ngày 1 tháng 1 năm 1970 lúc nửa đêm]. Bạn có thể sử dụng hàm tạo ngày để chuyển đổi dấu thời gian này thành đối tượng JavaScript Date
hữu ích hơn.File
cũng có hai thuộc tính khác: input
1 và input
2, đầu tiên trong số đó không được chấp nhận và không chuẩn khác, vì vậy bạn có thể nên tránh sử dụng chúng. Hãy nhớ rằng tất cả các thuộc tính này chỉ được đọc.Tệp & Blobs
File
, JavaScript còn có một cách khác để đại diện cho các tệp, được gọi là input
4input
4 chứa dữ liệu của tệp chung, cùng với thông tin về kích thước và loại của nó. File
thực sự chỉ là một input
4 chuyên dụng hơn, được sử dụng để thể hiện các tệp cụ thể trong hệ thống tập tin của người dùng. Nó kế thừa tất cả các phương thức và thuộc tính của Blob và chứa một số thông tin bổ sung về tên của tệp và ngày sửa đổi cuối cùng.
Hai cái này về cơ bản có thể hoán đổi cho nhau và bạn có thể sử dụng một ở hầu hết mọi nơi bạn có thể sử dụng cái kia. Nếu bạn hoàn toàn cần phải chuyển đổi chúng, bạn có thể làm như vậy bằng cách sử dụng hàm tạo loại khác.
Đọc nội dung của các tệp
Được rồi, vì vậy chúng tôi biết cách chọn và nhận thông tin về các tệp, nhưng làm thế nào để chúng tôi thực sự đọc những gì bên trong chúng? Chà, điều đó phụ thuộc vào loại tệp và những gì bạn muốn làm với nó. Đối với mục đích của bài viết này, chúng tôi sẽ chỉ tập trung vào hình ảnh và tệp văn bản.
Phương pháp đọc tệp linh hoạt và được hỗ trợ tốt nhất để đọc nội dung tệp là API Filereader. Nó có một API điều khiển sự kiện, vì vậy thay vì chỉ gọi một hàm và nhận nội dung của tệp, chúng ta phải thực hiện một số bước bổ sung.
Hãy bắt đầu với việc đọc một tệp văn bản:
- Đầu tiên, chúng tôi nhận phần tử đầu vào tệp và đăng ký trình nghe sự kiện thay đổi trên nó bằng cách gán chức năng gọi lại cho thuộc tính
input
8 của nóchange event listener on it by assigning a callback function to itsinput
8 property - Chúng tôi nhận được tệp đã chọn
- Chúng tôi kiểm tra xem một tệp có thực sự được chọn không và nếu không, [điều này có thể xảy ra chẳng hạn nếu người dùng nhấp vào ‘hủy trong cửa sổ lựa chọn], chúng tôi thoát khỏi chức năng
- Tiếp theo, chúng tôi tạo một thể hiện của Filereader
- Sau đó, chúng tôi đăng ký bất kỳ trình xử lý sự kiện mà chúng tôi có thể cần. Để truy cập các nội dung tệp, chúng tôi chỉ thực sự cần sự kiện tải, điều này kích hoạt khi thao tác đọc đã hoàn thành thành công. Tuy nhiên, nó thường là một ý tưởng tốt để đăng ký một trình xử lý lỗi. Một danh sách đầy đủ các sự kiện có thể có sẵn một chút vào bài viết, cùng với một số mẹo xử lý lỗi, vì vậy hãy tiếp tục đọc 😉load event, which triggers when the read operation has finished succesfully. However it’s usually a good idea to register an error handler as well. A full list of possible events is available a bit further into the article, along with some error handling tips, so keep reading 😉
- Sau khi tất cả người nghe sự kiện được đăng ký, chúng tôi bắt đầu hoạt động đọc bằng cách gọi một trong các phương thức Readas, trong trường hợp này
input
9 all event listeners are registered, we initiate the read operation by calling one of the readAs methods, in this caseinput
9 - Sau khi thao tác đọc kết thúc, nội dung tệp sẽ có sẵn trong thuộc tính
files
0 mà chúng ta có thể truy cập bên trong trình xử lý sự kiện tải [hàm gọi lạifiles
1].load event handler [thefiles
1 callback function].
Mẹo nhanh: Bạn có thể truy cập trình đọc bên trong một trình xử lý sự kiện theo nhiều cách: files
2. Hãy nhớ rằng files
3 không có sẵn trong các chức năng mũi tên. You can access the reader inside an event handler in multiple ways: files
2. Keep in mind
that files
3 is not available in arrow functions.
Xử lý lỗi
Trong trường hợp lỗi, trình xử lý sự kiện lỗi được gọi và bạn có thể tìm thấy đối tượng lỗi trong files
4. Mã lỗi có thể là:
files
5 - không tìm thấy tệpfiles
6 - Không thể đọc được tệpfiles
7 - Có vấn đề bảo mậtfiles
8 - ném khifiles
9 được gọi trong khi không có hoạt động đọc đang được tiến hành
Hầu hết thời gian không cần phải phân biệt giữa các loại lỗi này, có thể ngoại trừ File
0 thường vô hại và có thể bị bỏ qua.
Trạng thái sẵn sàng
Hoạt động đọc không đồng bộ, vì vậy don don thử truy cập files
0 ngay sau cuộc gọi Readas. Nếu bạn thực sự cần kiểm tra giá trị files
0 bên ngoài trình xử lý sự kiện tải, trước tiên hãy kiểm tra giá trị của File
3, đây sẽ là một trong 3 giá trị:asynchronous, so don’t try accessing files
0 right after the readAs call. If you really need to check the files
0 value outside of the load event handler, make sure to first
check the value of File
3, which will be one of 3 values:
File
4 - Người đọc đã được tạo, nhưng chưa có phương thức Readas nào được gọi. [TRỐNG RỖNG]readAs method was called yet. [EMPTY]File
5 - Một trong những phương pháp Readas đã được gọi. Một hoạt động đọc đang được tiến hành, và chưa có lỗi nào xảy ra. [ĐANG TẢI]readAs methods has been called. A read operation is in progress, and no errors have occurred yet. [LOADING]File
6 - Hoạt động đã kết thúc. Điều này có thể có nghĩa là một trong ba điều:File
đã được đọc thành công, một lỗi đọc đã xảy ra hoặcfiles
9 đã được gọi và hoạt động đã bị hủy bỏ. [XONG]
Thuộc tính files
0 sẽ chỉ được điền trong trường hợp hoạt động đọc thành công. Trong tất cả các trường hợp khác, nó sẽ là File
0.
Điều tương tự áp dụng cho files
4 cần được truy cập bên trong trình xử lý sự kiện lỗi.error event handler.
Các loại sự kiện Filereader
Chúng tôi đã khám phá hai loại sự kiện đọc phổ biến nhất, bây giờ hãy để nhanh chóng bao gồm phần còn lại. Filereader có sáu loại sự kiện:
File
2 - được kích hoạt khi hoạt động đọc được hoàn thành thành côngsuccessfully completedFile
3 - được kích hoạt khi hoạt động đọc gặp lỗiFile
4 - được kích hoạt định kỳ trong khiFile
hoặcinput
4 đang được đọc và chứa thông tin về tiến trình của hoạt động. Có thể được sử dụng để thực hiện thanh tải.File
7 - được kích hoạt khi hoạt động đọc bị hủy, tức là khifiles
9 được gọiFile
9 - được kích hoạt khi hoạt động đọc bắt đầuname
0 - được kích hoạt khi một thao tác đọc kết thúc, bất kể nó đã thành công hay không
Bạn có thể nhận thấy rằng các sự kiện Filereader hoạt động tương tự như các sự kiện DOM thông thường. Tôi thấy rằng suy nghĩ về họ như vậy làm cho việc hiểu bản chất phi tuyến tính, không đồng bộ của họ dễ dàng hơn rất nhiều.
Sidenote: Giống như với các sự kiện DOM, nó có thể đăng ký trình xử lý sự kiện bằng cách sử dụng name
1 hoặc bằng cách gán chức năng gọi lại cho thuộc tính "OneVentName" của người đọc. Just as with DOM
events, it’s possible to register event handlers by using name
1, or by assigning a callback function to the "oneventname" property of a reader.
Blob.text[]
Nó cũng đáng chú ý rằng để đọc các tệp văn bản tồn tại một phương thức mới hơn và đơn giản hơn: name
2. Hãy nhớ rằng File
chỉ là một input
4 với một số chức năng được thêm vào, vì vậy nó kế thừa tất cả các phương thức của Blob, bao gồm cả phương pháp này. Điều này có nghĩa là bạn có thể sử dụng phương pháp này trên cả Blobs và Tệp.
Có phải nó trông đẹp hơn? Tôi nghĩ rằng nó có, nhưng có một điều bắt được. API này khá mới và hỗ trợ trình duyệt vẫn còn khá kém.
Làm việc với hình ảnh
Bây giờ chúng ta đã biết cách đọc các tệp văn bản, hãy để Lừa chuyển sang một cái gì đó thú vị hơn: hình ảnh. Để minh họa chủ đề này, chúng tôi sẽ xây dựng một bản xem trước đơn giản về hình ảnh đã chọn.
Loại tập tin
Đầu tiên, hãy để đảm bảo rằng tệp đã chọn thực sự là một hình ảnh. Chúng ta có thể làm điều đó với sự trợ giúp của thuộc tính name
5.
Thuộc tính name
5, cho phép bạn chỉ định loại tệp nào mà người dùng sẽ được phép chọn. Nó sử dụng một danh sách phân tách dấu phẩy của các nhà xác định loại tệp duy nhất. Mỗi nhà xác định loại có thể ở một trong các định dạng sau:
- Một phần mở rộng tên tệp không phân biệt trường hợp, bắt đầu với một ký tự thời gian []]. Ví dụ:
name
7,name
8,name
9,size
0 - Một loại MIME, ví dụ:
size
1,size
2,size
3,size
4 size
5 có nghĩa là "bất kỳ tệp hình ảnh nào"size
6 có nghĩa là "bất kỳ tệp âm thanh nào"size
7 có nghĩa là "bất kỳ tệp video nào"
Bạn có thể trộn và kết hợp chúng để đặt trường hợp sử dụng cụ thể của bạn.
Xác thực HTML là hoàn hảo mặc dù. Ví dụ: trên Windows, nó sẽ chỉ ẩn các tệp không khớp với tiêu chí của bạn, nhưng bạn vẫn có thể chọn tất cả các tệp [*.*] Hoặc sử dụng kéo và thả để chọn bất kỳ tệp nào bạn muốn. Tất cả điều này có nghĩa là nó cũng là một ý tưởng tốt để kiểm tra loại tệp bên trong mã JavaScript của bạn.
Hoặc bạn có thể thiết lập các luồng xử lý riêng cho các loại tệp khác nhau
Thật không may, size
8 và size
9 không hoạt động trong các trình duyệt cũ như Internet Explorer, vì vậy nếu bạn cần hỗ trợ chúng, bạn có thể muốn xem xét một số cách giải quyết hoặc polyfills.
Ngoài ra, hãy nhớ rằng, bất kỳ tệp hình ảnh nào sẽ phù hợp [trong số những người khác]:
- Hình ảnh với hỗ trợ trình duyệt ít hơn hoàn hảo, như
type
0 - hình ảnh với độ trong suốt, như
type
1 - hình ảnh hoạt hình, như ________ 72
Vì vậy, hãy chắc chắn rằng bạn hỗ trợ tất cả các chức năng này hoặc chỉ định rõ ràng các loại bạn dự định hỗ trợ.
URL dữ liệu & URL đối tượng
Để hiển thị một hình ảnh đã chọn, chúng tôi sẽ cần HTML IMG và URL cho thuộc tính type
3. Có hai cách khác nhau để biểu diễn một tệp hình ảnh dưới dạng URL: DataUrl và ObjectURL. Có một số khác biệt quan trọng giữa hai người, vì vậy hãy nhanh chóng chạy qua chúng.dataURL and objectURL. There are some important differences between the two, so let's quickly run through them.
DataUrl
Nó kết quả của type
4. Đó là một chuỗi chứa loại của tệp và dữ liệu nhị phân thực tế của tệp, được mã hóa bằng base64.
Định dạng của nó có thể thay đổi một chút tùy thuộc vào loại dữ liệu mà nó đại diện, nhưng đối với hầu hết các tệp, có vẻ như thế này: type
5, trong đó type
6 là loại MIME và type
7 là tệp được mã hóa cơ sở64.
Bởi vì nó thực sự chứa dữ liệu tệp, nó có thể được sử dụng ở bất cứ đâu sau khi nó được tạo, mà không cần tệp gốc. Tuyệt đấy!
ObjectUrl
Còn được gọi là URL Blob. Nó kết quả của type
8. Nó là một API mới hơn, nhưng vẫn được hỗ trợ khá tốt. Tuy nhiên, nó sẽ không hoạt động trong IE phiên bản 9 trở xuống.blob URL. It’s the result of type
8. It is a newer API, but still pretty well supported. It won't however work in IE version 9 and lower.
Nó nhanh hơn và súc tích hơn type
9 nhưng nó đi kèm với những cơn đau đầu và hạn chế của riêng nó. Trái ngược với DataURL, nó không chứa bất kỳ dữ liệu tệp nào. Nó chỉ là một tham chiếu đến một tập tin. Một sự khác biệt quan trọng khác là thực tế là type
8 là đồng bộ.synchronous.
Đối tượng phải bị thu hồi khi nó không còn cần thiết. Trình duyệt sẽ tự động thực hiện nó khi tài liệu được dỡ xuống, tuy nhiên để sử dụng bộ nhớ và hiệu suất tối ưu, bạn không nên dựa vào hành vi đó, đặc biệt là trong các ứng dụng lớn với nhiều đối tượng. Thay vào đó, bạn nên gọi rõ ràng lastModified
1 khi URL không còn cần thiết, ví dụ như trong trình xử lý sự kiện lastModified
2 mà chúng tôi sẽ thảo luận sau.
Sidenote: Để lấy dữ liệu tệp được mã hóa cơ sở64 từ một dataurl, chỉ cần trích xuất một phần của chuỗi sau dấu phẩy, như thế này: lastModified
3to get the base64-encoded file data from a dataURL, simply extract the part of the string after the comma, like this: lastModified
3
Hiển thị hình ảnh đã chọn
Hầu hết các đối tượng thời gian và dataURL có thể được sử dụng thay thế cho nhau, nhưng mỗi người đều có điểm mạnh và điểm yếu riêng. Điều này có nghĩa là bạn có thể nên học cả hai và chọn cái nào sẽ sử dụng trên cơ sở từng trường hợp. Hãy cùng xem xét các ví dụ về cả hai, để có cảm giác tốt hơn về cách mỗi người hoạt động.
Sử dụng Filereader & DataURLS
- Chúng tôi đăng ký trình nghe sự kiện thay đổi trên đầu vào tệpchange event listener on the file input
- Bên trong cuộc gọi lại
input
8, chúng tôi nhận được tệp đã chọn và tạo một thể hiện làtype
9 - Chúng tôi đăng ký trình nghe sự kiện tải trên đầu đọcload event listener on the reader
- Bên trong cuộc gọi lại
lastModified
6, chúng tôi tạo một phần tử hình ảnh mới, - Sau đó, chúng tôi nhận được dataURL từ
files
0 [hãy nhớ,lastModified
8 chỉ vàolastModified
9] và gán nó cho thuộc tínhtype
3 như chúng tôi sẽ làm trong HTML - Khi thuộc tính SRC được đặt, chúng tôi nối toàn bộ phần tử
Date
1 vào DOM với tư cách là con của ReviewContainer của chúng tôi. .src attribute is set, we append the entireDate
1 element to the DOM as a child of our previewContainer. [We actually could have just created theDate
1 tag in HTML and updated the src attribute in javascript, but doing it this way actually prepares us for working with multiple images at once, and manipulating images in aDate
3] - Khi mọi thứ được thiết lập, chúng tôi bắt đầu thao tác đọc bằng
Date
4, điều này sẽ kích hoạt trình nghelastModified
6 của chúng tôi khi nó hoàn thành việc đọc tệp.
Sử dụng đối tượng
- Chúng tôi đăng ký trình nghe sự kiện thay đổi trên đầu vào tệpchange event listener on the file input
- Bên trong cuộc gọi lại
input
8, chúng tôi nhận được tệp đã chọn và tạo một thể hiện làtype
9 - Chúng tôi đăng ký trình nghe sự kiện tải trên đầu đọcload event handler on the image
- Bên trong cuộc gọi lại
lastModified
6, chúng tôi tạo một phần tử hình ảnh mới, - Sau đó, chúng tôi nhận được dataURL từ
files
0 [hãy nhớ,lastModified
8 chỉ vàolastModified
9] và gán nó cho thuộc tínhtype
3 như chúng tôi sẽ làm trong HTMLsrc attribute. - Khi thuộc tính SRC được đặt, chúng tôi nối toàn bộ phần tử
Date
1 vào DOM với tư cách là con của ReviewContainer của chúng tôi. . - Khi mọi thứ được thiết lập, chúng tôi bắt đầu thao tác đọc bằng
Date
4, điều này sẽ kích hoạt trình nghelastModified
6 của chúng tôi khi nó hoàn thành việc đọc tệp.src attribute is set, we append the entireDate
1 element to the DOM as a child of our previewContainer.
Sử dụng đối tượng Elsewhere you might see images created by using the Image constructor i.e. input
04. Most of the time it's equivalent to input
05 and I've never had any problems with either of them. However there might be some edge cases [described in this
StackOverflow thread], which seem to make the latter a more reliable option.
Bên trong cuộc gọi lại input
8, chúng tôi nhận được tệp đã chọn và tạo phần tử hình ảnh mới
Chúng tôi đăng ký một trình xử lý sự kiện tải trên hình ảnh
Bên trong cuộc gọi lại lastModified
6, lastModified
1 sẽ thu hồi ObjectURL sau khi hình ảnh được tải đầy đủ và URL không còn cần thiết nữa. Bước này là không cần thiết, nhưng rất được khuyến khích. Hãy nhớ rằng nếu bạn sẽ cần URL đó ở một nơi khác sau này, bạn không nên thu hồi nó.
Khi hình ảnh được tải đầy đủ, chúng tôi đã giành được đối tượng nữa. Vì vậy, bên trong cuộc gọi lại lastModified
6, chúng tôi thu hồi url đó. Để làm điều đó, chúng tôi chuyển nó như một lập luận cho lastModified
1. Chúng ta có thể lấy URL trực tiếp từ thuộc tính SRC của hình ảnh.According to the
w3c working draft, input
08 might be replaced by a regular input
07 in the near future. Fingers crossed 🤞
Chúng tôi tạo đối tượng, bằng cách chuyển tệp đã chọn làm đối số cho
type
8 và gán nó cho thuộc tínhtype
3.
Khi thuộc tính SRC được đặt, chúng tôi nối toàn bộ phần tử Date
1 vào DOM với tư cách là con của ReviewContainer của chúng tôi.
Sidenote: nơi khác bạn có thể thấy hình ảnh được tạo bằng cách sử dụng hàm tạo hình ảnh, tức là input
04. Hầu hết thời gian nó tương đương với input
05 và tôi chưa bao giờ gặp vấn đề gì với một trong hai. Tuy nhiên, có thể có một số trường hợp cạnh [được mô tả trong luồng StackOverflow này], dường như làm cho cái sau trở thành một lựa chọn đáng tin cậy hơn.
Filelist
Trước khi chúng tôi chuyển sang đọc nhiều tệp, hãy để xóa một cái gì đó. Thuộc tính files
thực sự không phải là input
07, mặc dù nó trông giống như một. Đó là một loại dữ liệu ____108 đặc biệt. Điều này có nghĩa là nó không có quyền truy cập vào các phương thức mảng thông thường [như input
09, input
10, input
11], vì vậy để lặp lại trong danh sách bạn sẽ phải sáng tạo. Tôi sẽ chỉ cho bạn một vài cách khác nhau để làm điều này, nhưng nếu bạn muốn biết thêm, hãy xem chủ đề Stackoverflow này.
Bạn cũng có thể nhận thấy rằng mặc dù chúng tôi chỉ làm việc với một tệp singe [cho đến bây giờ], chúng tôi luôn phải viết input
12. Đó là bởi vì bất kể thuộc tính input
13 có được đặt hay không, input
14 luôn luôn là input
08. Điều này có nghĩa là ngay cả khi đầu vào chỉ chấp nhận một tệp, bạn vẫn phải cung cấp chỉ mục, trong trường hợp của một mục duy nhất là 0.
Sidenote: Theo dự thảo làm việc của W3C, input
08 có thể được thay thế bằng một input
07 thông thường trong tương lai gần. Ngón tay vượt 🤞
Giao diện Filelist nên được coi là rủi ro vì xu hướng chung trên nền tảng web là thay thế các giao diện đó bằng đối tượng nền tảng mảng trong ECMAScript [ECMA-262]. Cụ thể, điều này có nghĩa là cú pháp của Filelist.Item [0] có nguy cơ; Hầu hết các chương trình sử dụng lập trình khác của Filelist dường như không bị ảnh hưởng bởi việc di chuyển cuối cùng sang loại mảng.
Cảm ơn vì đã đọc.
Nếu điều gì đó không rõ ràng, hoặc bạn muốn tôi mở rộng về một số chủ đề, hãy cho tôi biết trong các bình luận
Các bài viết thú vị khác
Ngoài ra, nếu bạn là một người hâm mộ Vivaldi như tôi, hãy xem trình tạo hình thu nhỏ Vivaldi của tôi, thì đó là một công cụ miễn phí mà tôi đã tạo ra vì tôi mệt mỏi khi tạo hình thu nhỏ theo cách thủ công. Nó sử dụng rất nhiều khái niệm từ bài đăng này và bạn có thể kiểm tra toàn bộ mã nguồn trên GitHub.