다운로드 중인 파일의 크기를 알고 싶습니다. 파일이 사전 할당되었으므로 를 사용하면 du -sd
최종 전체 크기만 반환됩니다. 나는 얼마나 많이 다운로드되었는지 알고 싶기 때문에 뒤에 오는 0바이트가 계산되는 것을 원하지 않습니다. 이 사이즈는 어떻게 구하나요?
aria2c
이는 중지된 다운로드를 쉽게 재개할 수 있고 다운로드 길이를 저장하지 않는 것 같기 때문에 가능합니다.해당 제어(세션) 파일. 나는 썼다스크립트total_length
.aria2
제어 파일 에서 읽습니다. 하지만 이는 다운로드 길이가 아닌 전체 길이입니다. 이 스크립트를 쉽게 사용할 수 있으며기술 사양aria2 스토어의 다른 속성을 가져옵니다.
댓글 업데이트:
ilkkachu가 암시했듯이 .aria2 파일의 BITFIELD는 실제로 맵인 것 같습니다. 각 비트는 파일 블록에 해당하며 1은 "다운로드됨"을 의미하고 0은 "다운로드되지 않음"을 의미합니다. 비트 필드 길이는 블록 수를 나타냅니다(블록 크기는 파일 크기를 블록 번호로 나눈 것일 수 있음). 다운로드 진행률은 BITFIELD의 청크 수에 대한 1초의 비율로 제공된다고 확신합니다. 안타깝게도 AFAICT, .aria2 파일은 지연 후 또는 다운로드가 중단된 후 즉시 업데이트되는 것 같습니다.
답변1
다운로드 진행 상황을 아는 문제만 고려하면 aria2
몇 가지 옵션이 있습니다.
설명에서 설명한 대로 이 정보는 filename.aria2
제어 파일( )의 비트맵에 있습니다. 에 기록되어 있어요https://aria2.github.io/manual/en/html/technical-notes.html. HTTP 다운로드는 처음부터 선형적이기 때문에 비트맵을 갖는 것은 HTTP 다운로드에 그다지 의미가 없지만 BitTorrent 다운로드 등에 대해서는 더 의미가 있다고 생각합니다.
다음은 다운로드한 특정 제어 파일의 16진수 덤프이며, 중요한 필드는 ( od -tx1 file.aria2
)로 표시되어 있습니다.
0000000 00 01 00 00 00 00 00 00 00 00 00 10 00 00 00 00
^^^^^^^^^^^ ^^^^^^
0000020 00 00 82 9d c0 00 00 00 00 00 00 00 00 00 00 00
^^^^^^^^^^^^^^^^^ ^^^^^^
0000040 01 06 ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^^^^^ ^^^...
0000060 ff ff ff ff ff ff ff ff ff fe 00 00 00 00 00 00
offset 10: 00 10 00 00 => piece length = 0x100000 = 1 MiB
offset 14: 00 00 00 00
82 9d c0 00 => file length = 0x829dc000 = 2191376384 (~ 2 GiB)
offset 30: 00 00 01 06 => size of bitmap = 0x0106 = 262 bytes, could fit 2096 pieces
offset 34: ff ff ... => bitmap
비트맵에 설정된 비트 수를 세어 보면 1MiB(200278016바이트)의 최소 191개 파일을 다운로드한 후 이 특정 다운로드가 중단되었습니다. 이는 제가 얻은 결과 파일 크기(201098200바이트)와 거의 일치합니다. (실제 파일은 MiB보다 크고 제어 파일에서 실행 중인 세그먼트의 로깅에 플래그가 지정될 수 있지만 상관하지 않습니다. 사전 할당을 활성화하지 않으므로 파일 시스템의 크기와 교차 확인할 수 있습니다. .)
기본적으로 aria2c
제어 파일은 60초마다 저장되지만 --auto-save-interval=<secs>
변경할 수 있습니다.
--auto-save-interval=<SEC>
Save a control file(*.aria2) every SEC seconds. If 0 is
given, a control file is not saved during download. aria2
saves a control file when it stops regardless of the
value. The possible values are between 0 to 600.
Default: 60
또는 aria2c --log=<logfile>
로그에서 다운로드 진행 상황을 사용하고 얻을 수도 있을 것 같습니다. 진행 상황 DEBUG
에서는 레벨 메시지의 쓰기 캐시 항목 만 표시하는 것처럼 보이지만 이를 활성화하면 로그가 상당히 장황해집니다.
또는 --summary-interval=1
일부 진행 상황 출력을 로 인쇄하고 stdout
일부 로그 파일로 리디렉션할 수도 있습니다( --show-console-readout=false
실시간 판독값을 숨길 수도 있음). 반올림된 숫자만 제공하는 것 같지만:
*** Download Progress Summary as of Wed May 13 12:57:11 2020 ***
=================================================================
[#b56779 1.7GiB/2.0GiB(86%) CN:1 DL:105MiB ETA:2s]
FILE: /work/blah.iso
-----------------------------------------------------------------
답변2
방법이 있습니다.
일치시키려는 것은 줄 끝의 0입니다. 이 정규식은 다음과 같습니다.
\0*$
정규식을 실행하는 도구가 \0
NUL 바이트( )를 차단 하지 않고 \0
이스케이프를 이해하는 경우 이 값은 일치됩니다. PCRE 정규 표현식을 사용하는 GNU grep은 이 작업을 수행합니다( -a
바이너리 허용, -o
인쇄오일치하는 부분만 -P
PCRE 정규식에 적용됩니다.)
grep -aPo '\0*$' file
그러면 각 줄의 끝에 모두 0바이트가 출력됩니다(각 줄 바꿈 문자 포함).
마지막 줄만 추출하려면 sed를 사용할 수 있습니다(GNU sed는 NUL이 포함된 파일을 처리하는 것으로 문서화되어 있습니다(이 -z
옵션 고려))(일부 도구는 NUL 바이트를 좋아하지 않습니다):
sed -n '$p' file | grep -aPo '\0*$'
수행해야 할 작업은 이를 계산하는 것입니다.
zerobytes=$(( $( sed -n '$p' file | grep -aPo '\0*$' | wc -c ) - 1 ))
물론, 이 시점에서 해야 할 일은 전체 파일 길이에서 이 값을 빼서 다운로드한 파일 크기를 구하는 것뿐입니다.
테스트되지 않은 코드
# alias ggrep and gdu to GNU grep and GNU du or install coreutils from Homebrew
filesize() {
local filename="$1"
test -e "$filename" || return 1
local filesize="$(gdu -sb "$filename" | awk '{ print $1 }')"
echo "$filesize"
}
filesizereal() {
local file="$1"
local zerobytes=$(( $( gsed -n '$p' "$file" | ggrep -aPo '\0*$' | wc -c ) - 1 ))
echo "$(( ${$(filesize "$file"):-0} - $zerobytes ))"
}
답변3
나는 후행 0을 계산하는 Rust 스크립트를 작성했습니다. 상당히 빠르지만 전체 파일을 로드합니다. 이것 좀 봐질문.
이 스크립트를 실행하려면 시스템에 설치되어 있어야 합니다 rust
. 내 시스템에서 이 스크립트의 이름을 지정 scriptisto
했습니다 .trailingzeroes.rs
#!/usr/bin/env scriptisto
// scriptisto-begin
// script_src: src/main.rs
// build_cmd: cargo build --release
// target_bin: ./target/release/script
// files:
// - path: Cargo.toml
// content: |
// package = { name = "script", version = "0.1.0", edition = "2018"}
// [dependencies]
// scriptisto-end
// https://users.rust-lang.org/t/count-trailing-zero-bytes-of-a-binary-file/42503/4
use std::env;
use std::fs;
fn main() {
let filename = env::args().nth(1).unwrap();
let buffer = fs::read(filename).unwrap();
let count = buffer.iter().rev().take_while(|b| **b == 0).count();
println!("{}", count);
}
지금,
# gdu is GNU du
# ggrep is GNU grep
function filesize() {
# '<file> ; returns size in bytes.'
local FILENAME="$1"
test -e "$FILENAME" || { echo "File $FILENAME doesn't exist." >&2 ; return 1 }
local SIZE="$(gdu -sb $FILENAME | awk '{ print $1 }')"
ec $SIZE
}
function filesizereal() {
local file="$1"
test -e "$file" || { echo "File $file doesn't exist." >&2 ; return 1 }
local zerobytes
# zerobytes=$(( $( ggrep -aPo '\0*$' $file | wc -c ) - 1 ))
zerobytes="${$(trailingzeroes.rs $file)}"
echo $(( ${$(filesize $file):-0} - $zerobytes ))
}