JSON 파일에 쓸 때 PathBuf 변수에서 백 슬래시 문자를 이스케이프하는 방법은 무엇입니까?

개빈 호프

저는 Rust를 처음 접했습니다.이 코드는 인공적인 학습 프로젝트의 일부입니다. 명심하십시오;)

튜플 컬렉션이 &[(i32, String, String, PathBuf)]있습니다. 데이터를 JSON 파일에 쓰도록 설계된 함수로 전달됩니다.

문제 : PathBuf를 a 로 변환 할 때 &str파일에 기록 된 경로에 이스케이프 처리되지 않은 백 슬래시 문자가 있으므로 JSON이 유효하지 않습니다.

코드는 다음과 같습니다.

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::path::PathBuf;

pub fn write_review_queue(ordered_review_queue: &[(i32, String, String, PathBuf)]) -> io::Result<()> {
    let output_file = "C:\\Dev\\Temp\\ReviewQueue\\review_queue.json";
    let mut buffer = try!(File::create(output_file));
    try!(buffer.write("{".to_string().as_bytes()));

    let mut is_first_item = true;
    for review_item in ordered_review_queue {
        if !is_first_item {
            try!(buffer.write(",".to_string().as_bytes()));
        }
        is_first_item = false;

        let json_string = "\"ReviewItem\": ".to_string() +
                          "{\"Index\": " + &review_item.0.to_string() + 
                          ", \"ReviewItemName\": \"" + &review_item.1 +
                          "\", \"ReviewItemPath\": \"" + &review_item.2 +
                          "\", \"MetadataPath\": \"" +  review_item.3.to_str().unwrap() +
                          "\"}";

        try!(buffer.write(json_string.as_bytes()));
    }


    try!(buffer.write("}".to_string().as_bytes()));
    Ok(())
}

출력의 예 :

{
    "ReviewItem": {
        "Index": 1,
        "ReviewItemName": "Crying Cat",
        "ReviewItemPath": "C:/Temp",
        "MetadataPath": "C:\Dev\Temp\ReviewQueue\Metadata\cryingcat.json"
    },
    "ReviewItem": {
        "Index": 2,
        "ReviewItemName": "Rusty Rat",
        "ReviewItemPath": "C:/Temp",
        "MetadataPath": "C:\Dev\Temp\ReviewQueue\Metadata\rustyrat.json"
    }
}

에 대한 PathBufs를 생성하는 코드 MetadataPath는 다음과 같습니다.

let metadata_files = metadata_read::read_filenames_from_dir("C:\\Dev\\Temp\\ReviewQueue\\Metadata");
    if !metadata_files.is_ok() {
        println!("reading metadata filenames failed");
        return;
    }

    let mut metadata_counts = Vec::new();
    for file in metadata_files.unwrap() {
        let metadata_field_count = metadata_read::count_nonempty_metadata_fields(&file, &keys);
        metadata_counts.push(metadata_field_count.unwrap());
    }

그리고 count_nonempty_metadata_fields기능 :

pub fn count_nonempty_metadata_fields(file_path: &PathBuf, metadata_keys: &[String]) -> Result<(i32, String, String, PathBuf), io::Error>
{
    // a bunch of code here...

    let path = file_path.to_path_buf();
    Ok((key_count, review_item_name, review_item_path, path))
}

원래 디렉터리 경로 문자열을 다음과 같이 변경하면

let metadata_files = metadata_read::read_filenames_from_dir("C:/Dev/Temp/ReviewQueue/Metadata");

출력을 변경합니다. 예 :

{
    "ReviewItem": {
        "Index": 1,
        "ReviewItemName": "Crying Cat",
        "ReviewItemPath": "C:/Temp",
        "MetadataPath": "C:/Dev/Temp/ReviewQueue/Metadata\cryingcat.json"
    },
    "ReviewItem": {
        "Index": 2,
        "ReviewItemName": "Rusty Rat",
        "ReviewItemPath": "C:/Temp",
        "MetadataPath": "C:/Dev/Temp/ReviewQueue/Metadata\rustyrat.json"
    }
}

그러나 그것은 여전히 ​​옳지 않습니다.

질문

  1. 나는 구축의 접근 방식을 고수하는 경우 String손으로 만들어진 JSON 형식, 어떻게의 경로 콘텐츠를받을 수 있나요 PathBuf정방향 슬래시와 형식으로의 또는 백 슬래시를 탈출? API에 뭔가 빠졌나요?
  2. Json데이터를 빌드하기 위해 객체를 사용해야합니까 (아마 더 신뢰할 수있을 것입니까)? 그렇다면 Json객체 의 내용 을 파일 에 쓰는 일반적인 방법은 무엇 입니까?
셰프 마스터

구조화 된 형식을 직접 생성하지 않는 것이 좋습니다. 결과적으로 출력 형식이 잘못 될 수 있기 때문입니다. 또한 출력에는 동일한 두 개의 키를 가진 객체가 있습니다. 유효 하지 않은 것은 아니지만 원하는 것이 아닐 수 있습니다.

이 경우 따옴표와 백 슬래시, 아포스트로피 및 앰퍼샌드를 피하려고 시도하면서 빠르게 벽에 부딪 힐 것입니다. 또한 마지막 항목을 손으로 추적해야합니다. 도서관이 열심히 일하게하십시오.

Rust를위한 두 가지 좋은 JSON 라이브러리가 있습니다 : rustc_serializeserde .

첫 번째 단계는 데이터에 대한 실제 유형을 만드는 것입니다. 튜플은 훌륭하지만 foo.1그 이름이 정말 기억 나 시나요 ... 아니면 그랬 foo.2나요?

그런 다음 슬라이스를 간단히 출력 할 수 있습니다.

extern crate rustc_serialize;

use rustc_serialize::json;

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::path::PathBuf;

#[derive(RustcEncodable)]
struct Item {
    index: i32,
    name: String,
    path: String,
    metadata_path: PathBuf,
}

fn write_review_queue(ordered_review_queue: &[Item]) -> io::Result<()> {
    let mut buffer = try!(File::create("/tmp/output"));

    write!(buffer, "{}", json::as_json(&ordered_review_queue))
}

fn main() {
    let a = [Item { index: 0, name: "He\"llo".into(), path: "Good\\bye".into(), metadata_path: PathBuf::from(r#"C:\path\with'n\special"\chars"#)}];
    write_review_queue(&a).expect("Failed");
}

불행히도 이것은 PathBuf추악한 방식으로 인쇄됩니다 .

[{"index":0,"name":"He\"llo","path":"Good\\bye","metadata_path":[67,58,92,112,97,116,104,92,119,105,116,104,39,110,92,115,112,101,99,105,97,108,34,92,99,104,97,114,115]}]

PathBufs는 문자열 아님 을 아는 것이 중요합니다 . 특히, 이들은 플랫폼에 의존하는 추상화입니다. 유닉스 계열 시스템에서 경로는 UTF-8이 아니라 거의 비슷한 바이트 모음이고 Windows에서는 UCS-2에 가깝지만 UCS-2가 아닙니다.

귀하의 경우에 대해 진정한 UTF-8로 변환하는 데 적합한 손실 변환을 결정해야합니다. 표준 라이브러리에 내장 된 to_string_lossy. 또한 ToJson더 많은 사용자 정의를 허용하기 위해 유형을 구현 합니다.

extern crate rustc_serialize;

use rustc_serialize::json::{self, ToJson, Json};

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::path::PathBuf;
use std::collections::BTreeMap;

struct Item {
    index: i32,
    name: String,
    path: String,
    metadata_path: PathBuf,
}

impl ToJson for Item {
    fn to_json(&self) -> Json {
        let mut obj = BTreeMap::new();
        obj.insert("Index".to_string(), self.index.to_json());
        obj.insert("ReviewItemName".to_string(), self.name.to_json());
        obj.insert("ReviewItemPath".to_string(), self.path.to_json());
        obj.insert("MetadataPath".to_string(), self.metadata_path.to_string_lossy().to_json());
        obj.to_json()
    }
}

fn write_review_queue(ordered_review_queue: &[Item]) -> io::Result<()> {
    let mut buffer = try!(File::create("/tmp/output"));

    write!(buffer, "{}", json::as_json(&ordered_review_queue.to_json()))
}

fn main() {
    let a = [Item { index: 0, name: "He\"llo".into(), path: "Good\\bye".into(), metadata_path: PathBuf::from(r#"C:\path\with'n\special"\chars"#)}];
    write_review_queue(&a).expect("Failed");
}

이것은 또한 객체의 키 이름을 바꿀 수있는 기회를 허용합니다 (이름이 나에게 매우 중복되는 것처럼 보임에도 불구하고).

[{"Index":0,"MetadataPath":"C:\\path\\with'n\\special\"\\chars","ReviewItemName":"He\"llo","ReviewItemPath":"Good\\bye"}]

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

백 슬래시를 파이썬에서 이스케이프 문자로 무시하는 방법은 무엇입니까?

분류에서Dev

`find ... -exec` 내부`sed`에서 백 슬래시를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

sed가 expect 명령에 사용될 때 백 슬래시를 이스케이프하는 적절한 방법은 무엇입니까?

분류에서Dev

Maven을 사용하여 필터링 된 속성 파일에서 백 슬래시를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

preg_match 패턴에서 슬래시 문자를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

패턴 대체의 대체 부분에서 백 슬래시를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

Windows 7에서 사용자를 전환 할 때 사용자 이름 앞에 추가 된 백 슬래시를 제거하는 방법은 무엇입니까?

분류에서Dev

데이터 프레임 열 이름에 백 슬래시 (\)를 삽입하는 방법은 무엇입니까?

분류에서Dev

탭으로 구분 된 텍스트 파일에서 열의 문자열 값 끝에서 백 슬래시를 제거하는 방법은 무엇입니까?

분류에서Dev

Ruby에서 작은 따옴표로 된 단일 백 슬래시를 이스케이프하는 이유는 무엇입니까?

분류에서Dev

정규식에서 슬래시 '\'를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

파일에 쓸 때 공백과 개행을 제거하는 방법은 무엇입니까?

분류에서Dev

hexdump 출력 형식 문자열에 백 슬래시 \를 포함하는 방법은 무엇입니까?

분류에서Dev

따옴표 백 슬래시를 위해 파이썬에서 대체하는 방법은 무엇입니까?

분류에서Dev

tiddlywiki에서 백틱 (`) 문자를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

문자열 변수에 이스케이프 시퀀스를 추가하는 방법은 무엇입니까?

분류에서Dev

이중 백 슬래시 유니 코드 문자를 Python에서 원본으로 변환하는 방법은 무엇입니까?

분류에서Dev

Json 문자열에서 이스케이프 문자를 제거하는 방법은 무엇입니까?

분류에서Dev

mv-파일 이름에서 백 슬래시를 이스케이프하는 방법?

분류에서Dev

문자열의 일부가 될 슬래시를 이스케이프하는 방법은 무엇입니까?

분류에서Dev

Linux Shell-json을 sed로 읽을 때 JQ에서 생성 한 이스케이프 문자를 제거하는 방법은 무엇입니까?

분류에서Dev

Bash 스크립트에서 이스케이프 문자를 무시하는 방법은 무엇입니까?

분류에서Dev

파일 컨텐츠 교체 팀 시티의 변수에서 백 슬래시를 이스케이프하는 방법

분류에서Dev

정규식에서 이스케이프 문자를 무시하는 방법은 무엇입니까?

분류에서Dev

json이 파일에있을 때 jq에 변수를 전달하는 방법은 무엇입니까?

분류에서Dev

이스케이프 시퀀스에서 변수를 사용하는 방법은 무엇입니까?

분류에서Dev

다른 운영 체제에서 파일에 쓸 때 원본 문자 (인코딩)를 보존하는 방법은 무엇입니까?

분류에서Dev

ANTLR4 문법에서 두 문자 이스케이프 시퀀스를 이스케이프하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

일부 변수 이름이 숫자로 시작할 때 Json을 Java 클래스에 매핑하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    백 슬래시를 파이썬에서 이스케이프 문자로 무시하는 방법은 무엇입니까?

  2. 2

    `find ... -exec` 내부`sed`에서 백 슬래시를 이스케이프하는 방법은 무엇입니까?

  3. 3

    sed가 expect 명령에 사용될 때 백 슬래시를 이스케이프하는 적절한 방법은 무엇입니까?

  4. 4

    Maven을 사용하여 필터링 된 속성 파일에서 백 슬래시를 이스케이프하는 방법은 무엇입니까?

  5. 5

    preg_match 패턴에서 슬래시 문자를 이스케이프하는 방법은 무엇입니까?

  6. 6

    패턴 대체의 대체 부분에서 백 슬래시를 이스케이프하는 방법은 무엇입니까?

  7. 7

    Windows 7에서 사용자를 전환 할 때 사용자 이름 앞에 추가 된 백 슬래시를 제거하는 방법은 무엇입니까?

  8. 8

    데이터 프레임 열 이름에 백 슬래시 (\)를 삽입하는 방법은 무엇입니까?

  9. 9

    탭으로 구분 된 텍스트 파일에서 열의 문자열 값 끝에서 백 슬래시를 제거하는 방법은 무엇입니까?

  10. 10

    Ruby에서 작은 따옴표로 된 단일 백 슬래시를 이스케이프하는 이유는 무엇입니까?

  11. 11

    정규식에서 슬래시 '\'를 이스케이프하는 방법은 무엇입니까?

  12. 12

    파일에 쓸 때 공백과 개행을 제거하는 방법은 무엇입니까?

  13. 13

    hexdump 출력 형식 문자열에 백 슬래시 \를 포함하는 방법은 무엇입니까?

  14. 14

    따옴표 백 슬래시를 위해 파이썬에서 대체하는 방법은 무엇입니까?

  15. 15

    tiddlywiki에서 백틱 (`) 문자를 이스케이프하는 방법은 무엇입니까?

  16. 16

    문자열 변수에 이스케이프 시퀀스를 추가하는 방법은 무엇입니까?

  17. 17

    이중 백 슬래시 유니 코드 문자를 Python에서 원본으로 변환하는 방법은 무엇입니까?

  18. 18

    Json 문자열에서 이스케이프 문자를 제거하는 방법은 무엇입니까?

  19. 19

    mv-파일 이름에서 백 슬래시를 이스케이프하는 방법?

  20. 20

    문자열의 일부가 될 슬래시를 이스케이프하는 방법은 무엇입니까?

  21. 21

    Linux Shell-json을 sed로 읽을 때 JQ에서 생성 한 이스케이프 문자를 제거하는 방법은 무엇입니까?

  22. 22

    Bash 스크립트에서 이스케이프 문자를 무시하는 방법은 무엇입니까?

  23. 23

    파일 컨텐츠 교체 팀 시티의 변수에서 백 슬래시를 이스케이프하는 방법

  24. 24

    정규식에서 이스케이프 문자를 무시하는 방법은 무엇입니까?

  25. 25

    json이 파일에있을 때 jq에 변수를 전달하는 방법은 무엇입니까?

  26. 26

    이스케이프 시퀀스에서 변수를 사용하는 방법은 무엇입니까?

  27. 27

    다른 운영 체제에서 파일에 쓸 때 원본 문자 (인코딩)를 보존하는 방법은 무엇입니까?

  28. 28

    ANTLR4 문법에서 두 문자 이스케이프 시퀀스를 이스케이프하는 가장 좋은 방법은 무엇입니까?

  29. 29

    일부 변수 이름이 숫자로 시작할 때 Json을 Java 클래스에 매핑하는 방법은 무엇입니까?

뜨겁다태그

보관