【问题标题】:Files Don't Hold Enough Characters?文件没有足够的字符?
【发布时间】:2013-08-02 10:29:22
【问题描述】:

我正在编写这个记事本应用程序,用户在其中输入他们想要的内容到EditText,它会将write 输入到文件中,然后他们可以在read 中输入TextView

这是我正在使用的 EditText 的 XML 代码:

<EditText
    android:id="@+id/txtWrite"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/btnLogOut"
    android:layout_marginTop="42dp"
    android:layout_toLeftOf="@+id/btnAppendd"
    android:ems="5"
    android:imeOptions="flagNoExtractUi"
    android:inputType="textMultiLine"
    android:maxLength="2147483646" />

max length 行是我尝试修复它的尝试,因为我认为input 对用户来说已经足够了。但是,它不起作用。

当我显示文件的 length 时,它说它是 1024,这是有道理的,考虑到我如何从文件中获取 input 数据:

try {
    char[] inputBuffer = new char[1024];
    FileInputStream fIn = openFileInput("txt");
    InputStreamReader isr = new InputStreamReader(fIn);
    isr.read(inputBuffer);
    String data = new String(inputBuffer);
    isr.close(); fIn.close();
    display.setText(data + '\n' + '\n' + data.length()); // data + 1024
}catch(Exception e){}

这就是我输入所有文件的方式(谷歌搜索),所以我假设 new char[1024] 是文件的 max length 只能是 1024 的原因。

有没有人知道另一种输入无限长度文件的方法?我什至不知道为什么一定是new char[1024]

这是我 write 到文件的方式,这很好,因为它是短代码:

FileOutputStream fos = openFileOutput("txt", Context.MODE_PRIVATE);
fos.write(...);
fos.close();

这是我完整的write 方法:

public void write()
{
    Button write = (Button)findViewById(R.id.btnWrite);
    write.setOnClickListener (new View.OnClickListener()
    {
        public void onClick(View v)
        {
            EditText writeText = (EditText)findViewById(R.id.txtWrite);
            try {
                FileOutputStream fos = openFileOutput("txt", Context.MODE_PRIVATE);
                fos.write(writeText.getText().toString().getBytes());
                fos.close();
            } catch(Exception e) {}
        }
    });
}

【问题讨论】:

  • 你为什么不直接改变这个尺寸,我怀疑它不会起作用,比如像5120这样的东西。
  • 我希望有一种方法让它尽可能大,因为我不想只输入任意数字。 2147483646 不起作用。
  • @g00dy 这将使用比必要更多的内存,并且您仍然无法读取超过该数量的任何内容。
  • @mikeyaworski - 使用当前的实现,这是不可能的,你一次读取 1024,你不能一次读取“未指定”长度的字符。
  • @g00dy 不起作用。方法中的return int 是910,所以它只读取前910个字符。

标签: java android file


【解决方案1】:

替换这个:

char[] inputBuffer = new char[1024];
FileInputStream fIn = openFileInput("txt");
InputStreamReader isr = new InputStreamReader(fIn);
isr.read(inputBuffer);
String data = new String(inputBuffer);

有了这个:

FileInputStream fIn = openFileInput("txt");
InputStreamReader isr = new InputStreamReader(fIn);
StringBuffer fileContent = new StringBuffer("");

char[] buffer = new char[1024];
int len;
while ((len = isr.read(buffer, 0, 1024)) != -1) {
    fileContent.append(new String(buffer, 0, len));
}

String data = fileContent.toString();
//be sure to call isr.close() and fIn.close()

部分借用here

【讨论】:

  • 基本上,您 (@Mike) 只读取了一次已满的缓冲区。您需要有一个循环并继续读取缓冲区,直到您读取整个文件。
  • ^ 这很有意义(不是讽刺)
  • @mikeaworski 文件有多大?
  • 此代码中存在潜在的严重错误。您一次读取 1024 个字节并假设可以使用默认字符集将它们转换为字符串,但默认字符集(在 Android 上)是 UTF8,这是一种可变长度编码。如果文件的第 1024 个字节是双字节字符的开头(或三字节字符的第一个或第二个字节,等等),这将导致该字符被替换为指示编码的标记字符错误。然后下一个缓冲区开始会乱序,所以开始的一些字符也会丢失。
  • 要修复上面的错误,我会像原来的提问者那样使用 InputStreamReader,并从 char[] 而不是这里使用的 byte[] 创建字符串。这改变了(实际上非​​常困难的)任务,即找出可以停止阅读系统的位置,而不是尝试自己做。
【解决方案2】:

您的代码仅在 1024 个或更少字符时才有效,这意味着它不能正常工作。背后的想法

char[] inputBuffer = new char[1024];

是您按 1024 大小的块读取 inputBuffer,您这样做直到读取函数返回 -1(达到 EOF)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-13
    • 2011-02-09
    • 2012-11-10
    • 2017-12-09
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    相关资源
    最近更新 更多