代码之家  ›  专栏  ›  技术社区  ›  Nathan

readFileSync找不到文件,即使文件存在于当前目录中

  •  1
  • Nathan  · 技术社区  · 2 年前

    我正在为我的SvelteKit项目开发Joke API,Bun作为运行时,TypeScript作为编程语言。我的笑话API包括从包含363个父亲笑话的文本文件中随机获取一行。为此,我显然不得不阅读文件。所以我实施了这个方法,效果很好。。。除了一个部分。文件读取器找不到该文件。我放入的文件位置是 ./jokes.txt ,这正是它的位置。然而,文件读取器说它就是找不到它。我想是因为我在使用 Bun.file 读取导致问题的文件,因为Bun相对较新,所以我尝试 readFileSync 但这也没用。

    这是我的代码:

    import { readFileSync } from "fs";
    
    import { db } from "$lib/db";
    import { sql } from "drizzle-orm";
    import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
    
    export async function GET() {
      let file = readFileSync("./jokes.txt", "utf-8");
    
      const jokes = file.split("\n");
    
      const today = new Date();
    
      const jokecords = sqliteTable("jokecords", {
        id: integer("id").primaryKey(),
        joke: text("joke"),
        month: text("month"),
        day: text("day")
      });
    
      const matches = await db.select().from(jokecords).where(
        sql`month = ${today.getMonth().toString()} and day = ${today.getDay().toString()}`
      );
    
      let joke;
    
      if (matches.length > 0) {
        joke = matches[0];
      }
      else {
        joke = jokes[Math.floor(Math.random() * jokes.length)];
        await db.insert(jokecords).values({
          joke: joke,
          month: today.getMonth().toString(),
          day: today.getDay().toString()
        });
      }
    
      return {
        joke: joke
      }
    }
    

    这是我的文件结构

    .sveltekit
    node_modules
    src
      lib
        db.ts
      routes
        api
          +server.ts
          jokes.txt
          jokes-backup.txt
        +layout.svelte
        +page.svelte
      app.d.ts
      app.html
      app.pcss
    static
    .gitignore
    .npmrc
    bun.lockb
    package.json
    postcss.config.cjs
    README.md
    svelte.config.js
    tailwind.config.cjs
    tsconfig.json
    vite.config.ts
    
    2 回复  |  直到 2 年前
        1
  •  0
  •   Rafael Fernandes    2 年前

    readFileSync 可以以未指定的方式运行,因为它取决于代码执行的相对路径,而不是当前文件。避免这种情况的最佳方法是始终将代码文件的位置与执行运行时进行比较并进行解析,如:

    const path = require("path");
    
    fs.readFileSync(path.resolve(__dirname, "./jokes.txt"), "utf-8")
    
        2
  •  0
  •   derpirscher    2 年前

    如果 readFileSync 投掷 ENOENT 坚持文件存在是有意义的。只是没有。大多数时候,错误的发生是因为你使用的路径没有指向你认为它指向的位置。

    相对路径 ./jokes.txt 指向调用文件所在的目录,但指向 当前工作目录 过程的一部分。当然,这并没有深入到文件结构中。尝试记录 process.cwd() 以查看当前工作目录是什么。

    您也可以使用 path.resolve('./jokes.txt') 看看,相对路径实际解析到哪里。当然,你不会找到 jokes.txt 那里

    如果您真的确定,您想读取与当前文件使用的目录相同的文件 __dirname

    readFileSync(path.join(__dirname, "jokes.txt"), "utf-8"); 
    

    只是一些与这个问题无关的言论

    • 使用 读取文件同步 async 上下文有点违背了的目的 异步 因为它会阻止执行。存在异步 fs promises API

    • 我不知道是什么 db 是,但是

      const matches = await db.select().from(jokecords).where(
        sql`month = ${today.getMonth().toString()} and day = ${today.getDay().toString()}`
      );
      

      使用字符串模板创建查询,这被认为是不好的风格,因为它可能会打开您的代码进行SQL注入。请改用参数化查询。